Open marsChenxin opened 8 months ago
我提供一个密钥例子:5cP1J0n032B02g27e4Mw08W28wa7Hh3P , 最后一位改成L,也可以解密5cP1J0n032B02g27e4Mw08W28wa7Hh3L
我也有同样的问题,原因是hexToArray方法的问题,因为给的密钥不是十六进制,hexToArray方法的parseInt(str.substr(i, 2)会返回 NaN,建议在hexToArray方法内先判断 str是否为十六进制字符串
目前这个库的 sm4 算法只能接收 array
或者 Hex
格式的 sm4 密钥,因为你传入的是字符串,所以库默认会认为你传入的是 Hex 字符串。
由于 Hex 的表示范围只有 0 1 2 3 4 5 6 7 8 9 a b c d e f
,你的密钥中含有 Hex 没办法表示的字母,所以转换时已经出错了。
超出范围的表示在 hexToArray()
方法中都会被转换为 NaN
或者高位数字
,运算时 NaN
会被作为 0x00
处理。
因此你上面的密钥 5cP1J0n032B02g27e4Mw08W28wa7Hh3P
和 5cP1J0n032B02g27e4Mw08W28wa7Hh3L
在运算时都会被转换为 5c00000032b00227e400080008a70003
处理,末尾的 3P
和 3L
转换后的结果都是 0x03
,所以使用时没有区别。
5c P1 J0 n0 32 B0 2g 27 e4 Mw 08 W2 8w a7 Hh 3P
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
5c NaN NaN NaN 32 b0 02 27 e4 NaN 08 NaN 08 a7 NaN 03
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
5c 00 00 00 32 b0 02 27 e4 00 08 00 08 a7 00 03
所以如果你将末尾字符 P 更改为 Hex 范围内(0 1 2 3 4 5 6 7 8 9 a b c d e f)的字符,你的加密结果就会随之会发生变化,解密也会发现无法解密了。
比如你可以将密钥改为 5cP1J0n032B02g27e4Mw08W28wa7Hh3f
,你就会发现结果不再一样了。
sm4 算法要求使用 16 字节的随机数作为密钥,你可以利用 crypto 模块直接生成 16 字节的密钥,然后使用 Hex 编码后得到一个合法的 Hex 格式密钥。
import crypto from "crypto";
// 生成随机数密钥
let randomKey = arrayToHex(Array.from(crypto.randomBytes(16).values()));
console.log(randomKey);
输出结果:
12605159ec0775f70a4dd08561a3dbff
我也有同样的问题,原因是hexToArray方法的问题,因为给的密钥不是十六进制,hexToArray方法的parseInt(str.substr(i, 2)会返回 NaN,建议在hexToArray方法内先判断 str是否为十六进制字符串
感谢
目前这个库的 sm4 算法只能接收
array
或者Hex
格式的 sm4 密钥,因为你传入的是字符串,所以库默认会认为你传入的是 Hex 字符串。由于 Hex 的表示范围只有
0 1 2 3 4 5 6 7 8 9 a b c d e f
,你的密钥中含有 Hex 没办法表示的字母,所以转换时已经出错了。超出范围的表示在
hexToArray()
方法中都会被转换为NaN
或者高位数字
,运算时NaN
会被作为0x00
处理。因此你上面的密钥
5cP1J0n032B02g27e4Mw08W28wa7Hh3P
和5cP1J0n032B02g27e4Mw08W28wa7Hh3L
在运算时都会被转换为5c00000032b00227e400080008a70003
处理,末尾的3P
和3L
转换后的结果都是0x03
,所以使用时没有区别。5c P1 J0 n0 32 B0 2g 27 e4 Mw 08 W2 8w a7 Hh 3P ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 5c NaN NaN NaN 32 b0 02 27 e4 NaN 08 NaN 08 a7 NaN 03 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 5c 00 00 00 32 b0 02 27 e4 00 08 00 08 a7 00 03
所以如果你将末尾字符 P 更改为 Hex 范围内(0 1 2 3 4 5 6 7 8 9 a b c d e f)的字符,你的加密结果就会随之会发生变化,解密也会发现无法解密了。
比如你可以将密钥改为
5cP1J0n032B02g27e4Mw08W28wa7Hh3f
,你就会发现结果不再一样了。sm4 算法要求使用 16 字节的随机数作为密钥,你可以利用 crypto 模块直接生成 16 字节的密钥,然后使用 Hex 编码后得到一个合法的 Hex 格式密钥。
import crypto from "crypto"; // 生成随机数密钥 let randomKey = arrayToHex(Array.from(crypto.randomBytes(16).values())); console.log(randomKey);
输出结果:
12605159ec0775f70a4dd08561a3dbff
感谢感谢
目前这个库的 sm4 算法只能接收
array
或者Hex
格式的 sm4 密钥,因为你传入的是字符串,所以库默认会认为你传入的是 Hex 字符串。由于 Hex 的表示范围只有
0 1 2 3 4 5 6 7 8 9 a b c d e f
,你的密钥中含有 Hex 没办法表示的字母,所以转换时已经出错了。超出范围的表示在
hexToArray()
方法中都会被转换为NaN
或者高位数字
,运算时NaN
会被作为0x00
处理。因此你上面的密钥
5cP1J0n032B02g27e4Mw08W28wa7Hh3P
和5cP1J0n032B02g27e4Mw08W28wa7Hh3L
在运算时都会被转换为5c00000032b00227e400080008a70003
处理,末尾的3P
和3L
转换后的结果都是0x03
,所以使用时没有区别。5c P1 J0 n0 32 B0 2g 27 e4 Mw 08 W2 8w a7 Hh 3P ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 5c NaN NaN NaN 32 b0 02 27 e4 NaN 08 NaN 08 a7 NaN 03 ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓ 5c 00 00 00 32 b0 02 27 e4 00 08 00 08 a7 00 03
所以如果你将末尾字符 P 更改为 Hex 范围内(0 1 2 3 4 5 6 7 8 9 a b c d e f)的字符,你的加密结果就会随之会发生变化,解密也会发现无法解密了。
比如你可以将密钥改为
5cP1J0n032B02g27e4Mw08W28wa7Hh3f
,你就会发现结果不再一样了。sm4 算法要求使用 16 字节的随机数作为密钥,你可以利用 crypto 模块直接生成 16 字节的密钥,然后使用 Hex 编码后得到一个合法的 Hex 格式密钥。
import crypto from "crypto"; // 生成随机数密钥 let randomKey = arrayToHex(Array.from(crypto.randomBytes(16).values())); console.log(randomKey);
输出结果:
12605159ec0775f70a4dd08561a3dbff
在这都能碰见你
在这都能碰见你
哈哈,就这么几个常用库😂
sm4 其他模式怎么使用呢?除了CBC模式,其他模式加密的结构都是一样的。 let smKey = stringToHex(secretKey.value); console.log(smKey) encrypted = sm4.encrypt(inputText.value, smKey, { mode: selectedMode.value.toLowerCase(), output: 'utf-8', iv: 'fedcba98765432100123456789abcdef', }); 是我的代码有问题吗
我发现有些sm4加密解密的密钥有点问题,例如我用A密钥加密后,改动A密钥的最后一位,一样可以解密出来,请问是不是我生成的密钥有什么问题