为啥对不上?好奇怪
1 、openresty github 官方示例
https://github.com/openresty/lua-resty-string
local aes = require "resty.aes"
local str = require "resty.string"
local aes_128_cbc_md5 = aes:new("AKeyForAES")
-- the default cipher is AES 128 CBC with 1 round of MD5
-- for the key and a nil salt
local encrypted = aes_128_cbc_md5:encrypt("Secret message!")
ngx.say("AES 128 CBC (MD5) Encrypted HEX: ", str.to_hex(encrypted))
ngx.say("AES 128 CBC (MD5) Decrypted: ", aes_128_cbc_md5:decrypt(encrypted))
2 、自己编写 lua 测试
local aes = require "resty.aes"
local str = require "resty.string"
local aes_128_cbc_md5 = aes:new("gOxiO7IIRthJ406X")
-- the default cipher is AES 128 CBC with 1 round of MD5
-- for the key and a nil salt
local encrypted = aes_128_cbc_md5:encrypt("hello")
ngx.say("AES 128 CBC (MD5) Encrypted HEX: ", str.to_hex(encrypted))
ngx.say("AES 128 CBC (MD5) Decrypted: ", aes_128_cbc_md5:decrypt(encrypted))
-- 输出结果
AES 128 CBC (MD5) Encrypted HEX: de6641e8a49ef1911a10d9ec88cc477b
AES 128 CBC (MD5) Decrypted: hello
3 、java 实现
@Test
public void testEncryptText() {
String key = "gOxiO7IIRthJ406X";
byte[] iv = new byte[16];
String text = "hello";
AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, SecureUtil.md5(key).getBytes(), iv);
System.out.println(aes.encryptHex(text));
// 输出:446d1192d40aa0d05e3c30392ac43ec3
aes = new AES(Mode.CBC, Padding.PKCS5Padding, key.getBytes(), iv);
System.out.println(aes.encryptHex(text));
// 输出:190ede3e1359a6e4d8ecf38c8f4bce63
}
1
kran 112 天前 via Android
虽然忘了具体参数,但可以匹配上。曾经做过。
|
2
kran 112 天前 via Android
```
@Provides @Singleton private Cipher provideAESEncryptCipher(GlobalConfig config) { var key = Base64.decode(config.getAesKey()); var cipher = Cipher.getInstance("AES/CBC/PKCS7Padding", new BouncyCastleProvider()); var iv = config.getAesIV().getBytes(StandardCharsets.US_ASCII); cipher.init(Cipher.ENCRYPT_MODE, new SecretKeySpec(key, "AES/CBC/PKCS7Padding"), new IvParameterSpec(iv)); return cipher; } } local c = aes:new(key, nil, aes.cipher(128,"cbc"), {iv="0123456789abcdef"}) local path = ngx.re.gsub(string.sub(ngx.var.uri, 2), '-', '+') local url, err = c:decrypt(ngx.decode_base64(path)) ``` |
4
kran 112 天前 via Android
iv 自己定的
|
5
kran 112 天前 via Android
随机 iv 我记得两边匹配不上
|
7
forvvvv123 112 天前 2
OP 意思是同样的 key ,同样的明文,2 和 3 结果不一样吗?
如果是这个意思的话,那是因为 cbc 模式要求有 iv ,正常的做法,每一次加密 iv 都是一个不一样的值,同样 key 同样明文,iv 不同获得的密文也不同; 接收方要解密的时候必须知道 key + iv 才能解密,一般是约定附加在密文开头或者指定另一个字段; 你这两个都没有明确设置 iv ,那得看 lua 的默认行为和 java 默认行为最终导致的进入运算的 iv 一不一样; op 可以手动设置 iv ,或者查查手册把 iv 打印出来 |
8
Citrus 112 天前 via iPhone 4
刚好研究过。OpenResty 的 AES 库实际是调用 OpenSSL ,如果你不显示指定 IV ,会用 key 生成一个 IV 。具体看这里: https://docs.openssl.org/3.1/man3/EVP_BytesToKey/
所以这个库调用的时候看起来没有传 IV ,但是却可以正常加解密,且用全 0 IV 无法解密。 你的 Java 代码,IV 没有初始化,也就是全 0 ,跟 OpenSSL 生成的肯定是对不上的。所以解密失败了。 如果你想用 Java 解,有两种方式。一是实现 EVP BytesToKey 函数,算一个正确的 IV 出来。二是在 Lua 里,自己传 IV 进去,不要用自动生成的。 |
9
Citrus 112 天前 via iPhone
@forvvvv123 不一样。OP 在 Lua 没指定,自动生成了。但是在 Java 指定了,指定了全 0 。
|
10
Citrus 112 天前 via iPhone
@dunhanson 自己可以解是因为 OpenResty 用了 OpenSSL 的 https://docs.openssl.org/3.1/man3/EVP_BytesToKey/ 函数根据 Password 算出了 IV ,所以同一个 Password 算出的 Key 和 IV 是一样的,所以才能解密。
|
11
forvvvv123 112 天前
楼上老哥解释的很详细; 原来 lua 是默认调用了一个 openssl 的自动生成 iv 的函数,不是用全 0 的 iv ;
其实一般做法 iv 都是自己写段逻辑自己生成的,用随机数也好,不重复生成的算法也好。 因为传输密文的时候这个 iv 怎么传得跟对方约定好的,是单独一个业务字段,还是放到开头结尾; 所以 iv 这块总是要自己处理的; |