【发布时间】:2019-06-10 13:29:53
【问题描述】:
我有在 ES256 算法中创建的私钥和公钥 .pem 文件。我想用私钥签署 JWT 令牌,以后可以用公钥检查。
在jwt.io我发现有多个库支持ES256:jose4j、nimbus-jose-jwt、jjwt、fusionauth-jwt、vertx-auth-jwt。不幸的是,我找不到任何从 pem 文件加载密钥并创建 JWT 令牌的示例。
示例 N1:
我将 pem 文件导入到 .keystore 中
openssl pkcs12 -export -in ES256-public-key.pem -inkey ES256-private-key.pem -out ~/keystore.p12 -name selfsigned -nocerts
我用以下代码尝试了 jose4j:
KeyStore store = KeyStore.getInstance("PKCS12");
store.load(new FileInputStream("/home/andrew/keystore.p12"), "test".toCharArray());
Key key = store.getKey("selfsigned", "test".toCharArray());
JsonWebEncryption jwe = new JsonWebEncryption();
jwe.setPayload("Hello World!");
jwe.setAlgorithmHeaderValue(KeyManagementAlgorithmIdentifiers.ECDH_ES_A256KW);
jwe.setEncryptionMethodHeaderParameter(ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256);
jwe.setKey(key);
String serializedJwe = jwe.getCompactSerialization();
System.out.println("Serialized Encrypted JWE: " + serializedJwe);
jwe = new JsonWebEncryption();
jwe.setAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
KeyManagementAlgorithmIdentifiers.ECDH_ES_A256KW));
jwe.setContentEncryptionAlgorithmConstraints(new AlgorithmConstraints(AlgorithmConstraints.ConstraintType.WHITELIST,
ContentEncryptionAlgorithmIdentifiers.AES_128_CBC_HMAC_SHA_256));
jwe.setKey(key);
jwe.setCompactSerialization(serializedJwe);
System.out.println("Payload: " + jwe.getPayload());
抛出异常:
Exception in thread "main" org.jose4j.lang.InvalidKeyException: Invalid key java.lang.ClassCastException: Cannot cast sun.security.ec.ECPrivateKeyImpl to java.security.interfaces.ECPublicKey
at org.jose4j.jwx.KeyValidationSupport.castKey(KeyValidationSupport.java:64)
at org.jose4j.jwe.EcdhKeyAgreementAlgorithm.validateEncryptionKey(EcdhKeyAgreementAlgorithm.java:188)
at org.jose4j.jwe.EcdhKeyAgreementWithAesKeyWrapAlgorithm.validateEncryptionKey(EcdhKeyAgreementWithAesKeyWrapAlgorithm.java:73)
at org.jose4j.jwe.JsonWebEncryption.getCompactSerialization(JsonWebEncryption.java:264)
at com.icthh.A.main(A.java:30)
我什至不明白为什么它需要公钥来创建 JWT 令牌。
示例 N2
private static void nimbus() throws IOException, JOSEException {
JWSObject jwsObject = new JWSObject(new JWSHeader(JWSAlgorithm.ES256),
new Payload("Hello, world!"));
// We need a 256-bit key for HS256 which must be pre-shared
byte[] sharedKey = IOUtils.toByteArray(new FileInputStream("/home/andrew/ES256-private-key.pem"));
// Apply the HMAC to the JWS object
jwsObject.sign(new MACSigner(sharedKey));
// Output in URL-safe format
System.out.println(jwsObject.serialize());
}
这会抛出:
Exception in thread "main" com.nimbusds.jose.JOSEException: The "ES256" algorithm is not supported by the JWS signer
at com.nimbusds.jose.JWSObject.ensureJWSSignerSupport(JWSObject.java:269)
at com.nimbusds.jose.JWSObject.sign(JWSObject.java:318)
at com.icthh.A.main(A.java:57)
示例 N3:
jjwt - 这个库似乎对 android 很好我什至不确定它是否能够签署令牌,因为 android 是一个客户端。
我想找到的是如何从 ES256 私钥和公钥创建签名 JWT 令牌的完整示例。
【问题讨论】: