为什么我的 Jose4j JSON Web 密钥会导致此 InvalidKeyException?
Why does my Jose4j JSON Web Key cause this InvalidKeyException?
我正在使用 Jose4j 对 Java 中的 JSON Web 令牌进行加密。
我创建一个键作为 JSON 格式的字符串传递给 JsonWebKey.Factory.newJwk
方法,因此:
String jwkJson = "{\"kty\":\"oct\",\"k\":\"5uP3r53cR37k3yPW\"}";
我把它传给工厂并得到一个 JsonWebKey (jwk)
回来。
然后将密钥(从 jwk.getKey()
方法)传递给 JsonWebEncryption 的 setKey()
方法。
我设置 AlgorithmHeaderValue
和 EncryptionMethodHeaderParameter
...
然后,当我调用 jwe.getCompactSerialization()
它抛出以下异常
org.jose4j.lang.InvalidKeyException:
Invalid key for JWE A128KW, expected a 128 bit key but a 96 bit key was provided.
我传入了 16 个字节,那么为什么它的计算结果是 96 位而不是 128?
您需要先对密钥字符串进行 base64 编码,然后再将其添加到 JSON 对象 jwkJson
。
例如
String pass = "5uP3r53cR37k3yPW";
String jwkJson = "{\"kty\":\"oct\",\"k\":\""+ Base64Url.encodeUtf8ByteRepresentation(pass) +"\"}";
在JsonWebKey 的工厂方法中,它从JSON 对象中检索到键(k) 值后,对其进行base64 解码。这具有将位模式表示的字符数减少 3 的效果(如果您没有先对其进行编码)。
至于为什么会出现这种情况,我有点疑惑。我会假设如果你使用一个二进制字符串来描述一个使用 8 位表示的字符串(UTF-8,Java 中的本机字符集),那么使用 6 位将二进制字符串重新解释为字符表示(base64),会产生更长的字符串!
用于对称密钥 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 对象的便捷方法。
我正在使用 Jose4j 对 Java 中的 JSON Web 令牌进行加密。
我创建一个键作为 JSON 格式的字符串传递给 JsonWebKey.Factory.newJwk
方法,因此:
String jwkJson = "{\"kty\":\"oct\",\"k\":\"5uP3r53cR37k3yPW\"}";
我把它传给工厂并得到一个 JsonWebKey (jwk)
回来。
然后将密钥(从 jwk.getKey()
方法)传递给 JsonWebEncryption 的 setKey()
方法。
我设置 AlgorithmHeaderValue
和 EncryptionMethodHeaderParameter
...
然后,当我调用 jwe.getCompactSerialization()
它抛出以下异常
org.jose4j.lang.InvalidKeyException:
Invalid key for JWE A128KW, expected a 128 bit key but a 96 bit key was provided.
我传入了 16 个字节,那么为什么它的计算结果是 96 位而不是 128?
您需要先对密钥字符串进行 base64 编码,然后再将其添加到 JSON 对象 jwkJson
。
例如
String pass = "5uP3r53cR37k3yPW";
String jwkJson = "{\"kty\":\"oct\",\"k\":\""+ Base64Url.encodeUtf8ByteRepresentation(pass) +"\"}";
在JsonWebKey 的工厂方法中,它从JSON 对象中检索到键(k) 值后,对其进行base64 解码。这具有将位模式表示的字符数减少 3 的效果(如果您没有先对其进行编码)。
至于为什么会出现这种情况,我有点疑惑。我会假设如果你使用一个二进制字符串来描述一个使用 8 位表示的字符串(UTF-8,Java 中的本机字符集),那么使用 6 位将二进制字符串重新解释为字符表示(base64),会产生更长的字符串!
用于对称密钥 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 对象的便捷方法。