【发布时间】:2021-12-17 05:35:37
【问题描述】:
我已经在 Javascript 上完成了 AES CTR 实现。现在我打算将加密的字节共享给 Java 以进行进一步处理。但是我无法将返回值从JavaScript's Uint8Array 分配给Java's byte[]。
下面是Uint8Array格式的示例数据(经过AES CTR加密)
[71, 193, 223, 190, 6, 104, 11, 235, 249, 96, 54, 192, 233, 41, 198, 188, 15, 218, 10, 0, 61, 95, 58, 122, 74, 169, 27, 228, 121, 224, 128, 124, 198, 183, 23, 36, 89, 105, 184, 59, 245, 115, 244, 22, 122, 207, 217, 219, 160, 2, 227, 175, 134, 66, 165, 73, 102, 52, 14, 150, 182, 187, 228, 173, 96, 68, 11, 35, 166, 247, 45, 18, 202, 99, 81, 185, 216, 240, 66, 10, 105, 122, 45, 83]
当我通过尝试从Java 中的JavaScript 接收到的硬编码值时,byte[] 下显示,我收到以下投诉。
byte[] resp = {71, 193, 223, 190, 6, 104, 11, 235, 249, 96, 54, 192, 233, 41, 198, 188, 15, 218, 10, 0, 61, 95, 58, 122, 74, 169, 27, 228, 121, 224, 128, 124, 198, 183, 23, 36, 89, 105, 184, 59, 245, 115, 244, 22, 122, 207, 217, 219, 160, 2, 227, 175, 134, 66, 165, 73, 102, 52, 14, 150, 182, 187, 228, 173, 96, 68, 11, 35, 166, 247, 45, 18, 202, 99, 81, 185, 216, 240, 66, 10, 105, 122, 45, 83};
// The complain is as follow:
Required type: byte
Provided: int
我这样做是为了解决上述问题:
byte[] resp = {71, (byte)193, (byte)223, (byte)190, 6, 104, 11, (byte)235, (byte)249, 96, 54, (byte)192, (byte)233, 41, (byte)198, (byte)188, 15, (byte)218, 10, 0, 61, 95, 58, 122, 74, (byte)169, 27, (byte)228, 121, (byte)224, (byte)128, 124, (byte)198, (byte)183, 23, 36, 89, 105, (byte)184, 59, (byte)245, 115, (byte)244, 22, 122, (byte)207, (byte)217, (byte)219, (byte)160, 2, (byte)227, (byte)175, (byte)134, 66, (byte)165, 73, 102, 52, 14, (byte)150, (byte)182, (byte)187, (byte)228, (byte)173, 96, 68, 11, 35, (byte)166, (byte)247, 45, 18, (byte)202, 99, 81, (byte)185, (byte)216, (byte)240, 66, 10, 105, 122, 45, 83};
下面是一些实现的代码
JS
var key = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
var textBytes = aesjs.utils.utf8.toBytes("textToEncrypt");
var aesCtr = new aesjs.ModeOfOperation.ctr(key, new aesjs.Counter(16));
var encryptedBytes = aesCtr.encrypt(textBytes);
# Outcome of encryptedBytes
[71, 193, 223, 190, 6, 104, 11, 235, 249, 96, 54, 192, 233, 41, 198, 188, 15, 218, 10, 0, 61, 95, 58, 122, 74, 169, 27, 228, 121, 224, 128, 124, 198, 183, 23, 36, 89, 105, 184, 59, 245, 115, 244, 22, 122, 207, 217, 219, 160, 2, 227, 175, 134, 66, 165, 73, 102, 52, 14, 150, 182, 187, 228, 173, 96, 68, 11, 35, 166, 247, 45, 18, 202, 99, 81, 185, 216, 240, 66, 10, 105, 122, 45, 83]
Java
byte[] keyBytes = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
byte[] ivBytes = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
# Here I assign the value I've received from `Javascript` into `resp`
byte[] resp = {71, (byte)193, (byte)223, (byte)190, 6, 104, 11, (byte)235, (byte)249, 96, 54, (byte)192, (byte)233, 41, (byte)198, (byte)188, 15, (byte)218, 10, 0, 61, 95, 58, 122, 74, (byte)169, 27, (byte)228, 121, (byte)224, (byte)128, 124, (byte)198, (byte)183, 23, 36, 89, 105, (byte)184, 59, (byte)245, 115, (byte)244, 22, 122, (byte)207, (byte)217, (byte)219, (byte)160, 2, (byte)227, (byte)175, (byte)134, 66, (byte)165, 73, 102, 52, 14, (byte)150, (byte)182, (byte)187, (byte)228, (byte)173, 96, 68, 11, 35, (byte)166, (byte)247, 45, 18, (byte)202, 99, 81, (byte)185, (byte)216, (byte)240, 66, 10, 105, 122, 45, 83};
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
byte[] plaintext = cipher.doFinal(decoded);
String plaintextString = new String(plaintext, StandardCharsets.UTF_8);
# Here I expect the value `textToEncrypt` to be decrypted under variable `plaintextString`.
我做错了吗?例如,我在Java 中设置计数器(IV)的方式。
仅供参考
- cipher.getAlgorithm() 是 SunJCE 版本 15
【问题讨论】:
-
在生成的
Uint8Array周围尝试new Int8Array(…)。让我想起了JavaScript equivalent of Java's String.getBytes(StandardCharsets.UTF_8)。 -
CTR 模式不使用填充,即密文应与明文具有相同的长度,因此对于
textToEncrypt13 个字节。你的密文比较长,所以数据不一致(可能textToEncrypt是个假人,那么请分享属于贴出来的密文的明文)。 -
另外,Java代码中应用的IV不正确。在Java代码中使用的
new aesjs.Counter(16)对应的IV是{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}。如果我应用这个IV,我可以用Java代码成功地从JavaScript中解密密文。 -
@SebastianSimon,感谢分享链接。当我尝试在 Javascript 中做同样的事情时,这将对我有所帮助。要在 Java 中处理这个问题,你会建议我在
byte[]中处理它们吗?您可能已经注意到,从 Javascript 生成的一些值被视为Int。我不能直接接受这个参数作为byte[],Java会自己改变值。 -
@Topaco 眼光敏锐。是的,我提供了一个虚拟数据作为样本。先生,向您鞠躬 90 度,当您指向
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16}时,您已更正了我的 IV 计数器。我不太确定如何早点做到这一点。如果您可以将此作为答案发布,我愿意接受:) 谢谢!
标签: javascript java encryption aes