Prevent accidental leakage of private key details from JWKs
The JPSK implementation that we have now incorporates the public and private parts in a single class. There is risk of leaking the private key details on public JWK serialisation with toJSONObject() - the developer loads the key pair but then forgets to make a JWK copy with the public params only.
Solution 1:
Add a toJSONObject(boolean includePrivate) method, then let the existing no arg method call toJSONObject(false).
JSONObject publicJWK = jwk.toJSONObject()
JSONObject privateJWK = jwk.toJSONObject(true);
Pros: A single object representation, with simple choice how to output JSON object with public only or public + private params.
Cons: The private / public property cannot be inferred from the class name; also, the full constructor allows for specifying incomplete private key representations.
Solution 2:
Extend public ECKey and public RSAKey with PrivateECKey and PrivateRSAKey.
Pros: Whether the key is public or private can be inferred from the class name.
Cons: Explicit type casting of PrivateECKey / PrivateRSAKey to ECKey / RSAKey required to serialise the public params with toJSONObject. The danger of the developer forgetting that can be mitigated by using the toJSONObject(boolean) method described in 1.
Solution 3:
Use the existing Java model: Base abstract ECKey, with extending PublicECKey and PrivateECKey classes. Similar for RSA key.
java.security.interfaces.RSAKey
java.security.interfaces.RSAPublicKey
java.security.interfaces.RSAPrivateKey
Pros and cons: Same as with 2.
Comments (3)
-
reporter -
Alternate proposal to Solution 1 checked into branch native-keys:
JWK defines new method toPublicJWK which returns a copy of the JWK with only the public keys defined. All serialization methods simply serialize the whole key object. Use would be:
RSAKey key = ... // public and private keypair RSA JWK
RSAKey pub = key.toPublicJWK();
pub.toJSONString(); // serialize the public key
-
reporter - changed status to resolved
I like this. I just extended the call-through to JWKSet.toJSONObject() / JWKSet.toJSONObject(boolean) - see commit af8f30c.
- Log in to comment
Solution 2 implemented in branch iss22, see commit 7476435 :
ECPublicKey and RSAPublicKey store the public parameters.
ECKeyPair and RSAKeyPair extend ECPublicKey and RSAPublicKey with private parameters.
The existing toJSONObject() method of JWK and JWKSet will only include the public parameters in the output JSON, to prevent accidental leakage of sensitive key details. Added a second toJSONObject(boolean includeNonPublicParams) method that controls explicitly the inclusion of non-public params.
Also moved all JWK-related classes to a separate package, to unclutter the base JOSE package and for greater clarity.
The JavaDocs for this commit are at http://nimbusds.com/files/jose-jwt/javadoc/