TOTP / HOTP / HmacSHA256 与 Java 中的无符号字节键

在 TOTP / HOTP / HmacSHA256 用例中使用密钥时,Java 并不能很好地发挥作用。我的分析是以下原因引起的麻烦:

  • String.getBytes 将(当然)为字符值 > 127 的字符提供负字节值;

  • javax.crypto.Macjavax.crypto.spec.SecretKeySpec在外部和内部byte[]用于接受和转换密钥。

我们已经获得了一些飞天C-200单键OTP设备,它们带有一个由字节值> 127组成的十六进制字符串秘密。

我们已经成功地在 Ruby 中为这些令牌创建了一个 PoC,它完美地工作。由于我们想将这些集成到Keycloak 中,我们需要找到一个 Java 解决方案。

由于我们看到的 TOTP / HOTP / HmacSHA256 的每个实现都使用了该javax.cryptobyte[],我们担心我们必须重写所有使用过的类,但int为了支持这种情况。

问:还有别的方法吗?我们如何在 Java 中的 HmacSHA256 计算中使用秘密,其中字节的值 > 127 而不必重写所有内容?


更新

我看错了方向。我的问题是,密钥表示的字符串(UTF-16在Java中),其包含在被分解成Unicode字符2个的字节getBytes(),在通入之前SecretKeySpec

强制StandardCharsets.ISO_8859_1执行此转换可解决此问题。


月关宝盒
浏览 277回答 3
3回答

一只萌萌小番薯

签名与未签名是一个主要与人类相关的演示问题。计算机不知道或不关心是否0xFF意味着-1或255对您。所以不,你不需要使用整数,使用byte[]效果很好。这并不意味着您不能破坏事物,因为某些操作基于默认的有符号变量类型工作。例如:byte b = (byte)255;    // b is -1 or 255, depending on how you interpret itint i = b;      // i is -1 or 2³² instead of 255int u = b & 0xFF; // u is 255Java 只对原语进行了签名(boolean而char不是承受),这似乎让很多人望而却步。然而,Java 完全有能力执行加密操作,所以所有这些“不可能”的问题都只是用户错误。在编写安全敏感代码时,这不是您想要的。

偶然的你

不要害怕 Java :) 我已经测试了来自不同供应商的几十个令牌,Java 一切都很好,你只需要选择正确的转换器。从 String 获取字节作为 getBytes() 而不是使用适当的转换器是常见的问题。您从供应商那里获得的文件以十六进制格式表示密钥,因此只需谷歌“java 十六进制字符串到字节数组”并选择适合您的解决方案。Hex、Base32、Base64 只是一种表示,您可以轻松地从一种转换到另一种。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java