在 TOTP / HOTP / HmacSHA256 用例中使用密钥时,Java 并不能很好地发挥作用。我的分析是以下原因引起的麻烦:String.getBytes 将(当然)为字符值 > 127 的字符提供负字节值;javax.crypto.Mac并javax.crypto.spec.SecretKeySpec在外部和内部byte[]用于接受和转换密钥。我们已经获得了一些飞天C-200单键OTP设备,它们带有一个由字节值> 127组成的十六进制字符串秘密。我们已经成功地在 Ruby 中为这些令牌创建了一个 PoC,它完美地工作。由于我们想将这些集成到Keycloak 中,我们需要找到一个 Java 解决方案。由于我们看到的 TOTP / HOTP / HmacSHA256 的每个实现都使用了该javax.crypto库byte[],我们担心我们必须重写所有使用过的类,但int为了支持这种情况。问:还有别的方法吗?我们如何在 Java 中的 HmacSHA256 计算中使用秘密,其中字节的值 > 127 而不必重写所有内容?更新我看错了方向。我的问题是,密钥表示的字符串(UTF-16在Java中),其包含在被分解成Unicode字符2个的字节getBytes(),在通入之前SecretKeySpec。强制StandardCharsets.ISO_8859_1执行此转换可解决此问题。
3 回答
一只萌萌小番薯
TA贡献1795条经验 获得超7个赞
签名与未签名是一个主要与人类相关的演示问题。计算机不知道或不关心是否0xFF意味着-1或255对您。所以不,你不需要使用整数,使用byte[]效果很好。
这并不意味着您不能破坏事物,因为某些操作基于默认的有符号变量类型工作。例如:
byte b = (byte)255; // b is -1 or 255, depending on how you interpret it
int i = b; // i is -1 or 2³² instead of 255
int u = b & 0xFF; // u is 255
Java 只对原语进行了签名(boolean而char不是承受),这似乎让很多人望而却步。然而,Java 完全有能力执行加密操作,所以所有这些“不可能”的问题都只是用户错误。在编写安全敏感代码时,这不是您想要的。
偶然的你
TA贡献1841条经验 获得超3个赞
不要害怕 Java :) 我已经测试了来自不同供应商的几十个令牌,Java 一切都很好,你只需要选择正确的转换器。
从 String 获取字节作为 getBytes() 而不是使用适当的转换器是常见的问题。您从供应商那里获得的文件以十六进制格式表示密钥,因此只需谷歌“java 十六进制字符串到字节数组”并选择适合您的解决方案。
Hex、Base32、Base64 只是一种表示,您可以轻松地从一种转换到另一种。
添加回答
举报
0/150
提交
取消