【发布时间】:2019-01-26 18:25:35
【问题描述】:
从以下问题我们可以看出:
Java vs. Golang for HOTP (rfc-4226)
,当在 TOTP / HOTP / HmacSHA256 用例中使用密钥时,Java 并不能很好地发挥作用。我的分析是以下造成的麻烦:
-
String.getBytes(当然)会为字符值 > 127 的字符提供负字节值; -
javax.crypto.Mac和javax.crypto.spec.SecretKeySpec在外部和内部都使用byte[]来接受和转换密钥。
我们已经获得了一些Feitian C-200 Single Button OTP devices,它们带有一个十六进制字符串秘密,由大于 127 的字节值组成。
我们已经成功地在 Ruby 中为这些令牌创建了一个 PoC,它可以完美运行。由于我们要在Keycloak 中集成这些,所以我们需要找到一个Java 解决方案。
由于我们看到的每个 TOTP / HOTP / HmacSHA256 实现都使用javax.crypto 库和byte[],我们担心我们必须重写所有使用的类,但使用int 来支持这种情况。
问:还有其他方法吗?我们如何在 Java 中的 HmacSHA256 计算中使用秘密,其中字节的值 > 127 而无需重写所有内容?
更新
我看错了方向。我的问题是密钥被表示为一个字符串(Java 中的 UTF-16),其中包含由 getBytes() 分解为 两个 字节的 Unicode 字符,然后被传递到 SecretKeySpec。
在此转换上强制 StandardCharsets.ISO_8859_1 可以解决问题。
【问题讨论】:
-
Java 加密将字节视为无符号并且工作正常,几十年来一直为数十亿用户工作良好;请参阅我对您的第一个链接问题的新答案,该答案证明了这一点。
标签: java cryptography hmac one-time-password totp