1

我正在使用 Jose4j 在 Java 中执行 JSON Web Token 的加密。

我创建一个键作为 JSON 格式的字符串传递给JsonWebKey.Factory.newJwk方法,因此:

    String jwkJson = "{\"kty\":\"oct\",\"k\":\"5uP3r53cR37k3yPW\"}";

我把它传给工厂并得到JsonWebKey (jwk)回报。然后将密钥(来自jwk.getKey()方法)传递给 JsonWebEncryption 的setKey()方法。我设置AlgorithmHeaderValueEncryptionMethodHeaderParameter...

然后,当我调用jwe.getCompactSerialization()它时会引发以下异常

    org.jose4j.lang.InvalidKeyException: 
    Invalid key for JWE A128KW, expected a 128 bit key but a 96 bit key was provided.

我传入了 16 个字节,那么为什么这会计算为 128 的 96 位?

4

2 回答 2

2

在将密钥字符串添加到 JSON 对象之前,您需要对其进行 base64 编码jwkJson

例如

    String pass = "5uP3r53cR37k3yPW";
    String jwkJson = "{\"kty\":\"oct\",\"k\":\""+ Base64Url.encodeUtf8ByteRepresentation(pass) +"\"}";

在 JsonWebKey 的工厂方法中,它从 JSON 对象中检索到 key (k) 值后,它会对其进行 base64 解码。这具有将位模式表示的字符数减少 3 的效果(如果您没有先对其进行编码)。

至于为什么会出现这种情况,我有点困惑。我假设如果您使用一个二进制字符串来描述一个使用 8 位表示(UTF-8,Java 中的本机字符集)的字符串,那么使用 6 位表示(base64)将该二进制字符串重新解释为字符, 会产生更长的字符串!

于 2017-05-03T10:42:45.337 回答
2

用于对称密钥 base64url 的“oct”JWK 密钥类型对“k”参数值的密钥值进行编码(请参阅https://www.rfc-editor.org/rfc/rfc7518#section-6.4)。虽然“5uP3r53cR37k3yPW”是 16 个字符,但它使用 base64url 字母表并在作为 JWK 键值处理时解码为 12 个字节(96 位)的原始数据。k 值需要更长一点才能表示 16 字节/128 位。例如,类似String jwkJson = "{\"kty\":\"oct\",\"k\":\"5uP3r53cR37k3yPWj_____\"}";128 位对称 JWK 的东西可以与您正在做的事情一起使用。但是,加密密钥确实应该使用安全的随机数生成而不是看起来像密码的东西来创建。FWIW,JsonWebKey jwk = OctJwkGenerator.generateJwk(128);可能是生成 128 位对称 JWK 对象的一种便捷方式。

于 2017-05-05T12:21:30.957 回答