使用 OpenResty 的 resty.aes 模块解密 Java Cipher.getInstance("AES/CBC/NoPadding") 失败
2017-8-3 4:18:21
收藏:0
阅读:329
评论:1
我正在开发一个基于 nginx(OpenResty)的 Lua 模块,其中一个要求是对由一款旧版 Java 程序生成的加密字符串进行解密。但我的 Lua 代码无法解密它,我在这里寻求帮助。
合适的 Java 加密和解密代码:
public class AesCbc {
private static String PLAIN = "usr/passwd@bizdb:127.0.0.1:5432";
public static void main(String[] args) throws Exception {
Cipher aesCipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec("1234567890ABCDEF".getBytes(), "AES");
IvParameterSpec iv = new IvParameterSpec("fedcba0987654321".getBytes());
aesCipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
byte[] rawBytes = PLAIN.getBytes();
byte[] aligned;
int mod = rawBytes.length % 16; // prevent javax.crypto.IllegalBlockSizeException
if (mod == 0) {
aligned = new byte[rawBytes.length];
} else {
aligned = new byte[rawBytes.length + 16 - mod];
}
System.arraycopy(rawBytes, 0, aligned, 0, rawBytes.length);
byte[] cipherBytes = aesCipher.doFinal(aligned);
String base64Result = Base64.getEncoder().encodeToString(cipherBytes);
System.out.println("cipher:[" + base64Result + "], rawBytes.length=" + rawBytes.length + ", mod=" + mod);
aesCipher.init(Cipher.DECRYPT_MODE, keySpec, iv);
cipherBytes = Base64.getDecoder().decode(base64Result);
aligned = aesCipher.doFinal(cipherBytes);
int posNil;
for (posNil = 0; posNil < aligned.length; posNil++) {
if (aligned[posNil] == 0x00)
break;
}
rawBytes = new byte[posNil];
System.arraycopy(aligned, 0, rawBytes, 0, posNil);
String plain = new String(rawBytes);
System.out.println("plain:[" + plain + "], posNil=" + posNil + ", aligned.length=" + aligned.length);
}
}
Java 代码的输出结果:
cipher:[l1buytGEL4RKa/RezInQ3dJxvMtL6nyE2wTi7VyoS4w=], rawBytes.length=31, mod=15
plain:[usr/passwd@bizdb:127.0.0.1:5432], posNil=31, aligned.length=32
我在 nginx.conf->http->server 段中声明了我的 Lua 测试文件:
location /aescbc {
content_by_lua_file conf/aescbc.lua;
}
conf/aescbc.lua 的内容:
-- aescbc.lua
local aes = require "resty.aes"
local str = require "resty.string"
local aes128Cbc = aes:new("1234567890ABCDEF", nil, aes.cipher(128, "cbc"), {iv="fedcba0987654321"})
-- 在我的测试中使用了 AesCbc.java 的结果
local BASE64CIPHER = "l1buytGEL4RKa/RezInQ3dJxvMtL6nyE2wTi7VyoS4w="
local cipherBytes = ngx.decode_base64(BASE64CIPHER)
if not cipherBytes then
ngx.log(ngx.WARN, "decode base64 [" .. BASE64CIPHER .. "] failed")
return
end
local aligned = aes128Cbc:decrypt(cipherBytes)
if not aligned then
ngx.log(ngx.WARN, "decrypt cipherBytes [" .. str.to_hex(cipherBytes) .. "] failed")
return
end
ngx.log(ngx.NOTICE, "aligned [" .. str.to_hex(aligned) .. "]")
return
当使用 "curl http://127.0.0.1:8080/aescbc" 进行测试时,nginx 的错误日志如下:
2017/08/03 11:28:26 [warn] 13799#0: *5 [lua] aescbc.lua:18: decrypt cipherBytes [9756eecad1842f844a6bf45ecc89d0ddd271bccb4bea7c84db04e2ed5ca84b8c] failed, client: 127.0.0.1, server: , request: "GET /aescbc HTTP/1.1", host: "127.0.0.1:8080"
我认为我的 resty.aes 的使用方式一定有问题,但是我该如何修复?
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- Lua 虚拟机加密load(string.dump(function)) 后执行失败问题如何解决
- 我想创建一个 Nginx 规则,禁止访问
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?

经过在网上搜索、阅读 man 页面并进行一些实验几天后,问题终于解决了。因此,我自己回答了这个问题:
resty.aes 模块使用 OpenSSL 的默认 PKCS7 填充算法,在当前版本的 resty.aes 中没有设置 NoPadding 选项的方法。因此,我对其进行了修补:(添加了一个 padding 参数并在 aes:new 中调用了 _EVP_CIPHER_CTX_set_padding()_)
$ diff ./lualib/resty/aes.lua.orig ./lualib/resty/aes.lua 79a80 > int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *x, int padding); 128c129 < function _M.new(self, key, salt, _cipher, _hash, hash_rounds) --- > function _M.new(self, key, salt, _cipher, _hash, hash_rounds, padding) 177a179,184 > end > > if padding then > -- 0:NoPadding, 1:PKCS7(default), 2:ISO7816_4, 3:ANSI923, 4:ISO10126, 5:ZERO > C.EVP_CIPHER_CTX_set_padding(encrypt_ctx, padding); > C.EVP_CIPHER_CTX_set_padding(decrypt_ctx, padding);并对 lua 测试代码进行了一些小修改:
$ cat ./nginx/conf/aescbc.lua -- aescbc.lua local aes = require "resty.aes" local str = require "resty.string" local aes128Cbc = aes:new("1234567890ABCDEF", nil, aes.cipher(128, "cbc"), {iv="fedcba0987654321"}, nil, 0) -- result of AesCbc.java for my test local BASE64CIPHER = "l1buytGEL4RKa/RezInQ3dJxvMtL6nyE2wTi7VyoS4w=" local cipherBytes = ngx.decode_base64(BASE64CIPHER) if not cipherBytes then ngx.log(ngx.WARN, "decode base64 [" .. BASE64CIPHER .. "] failed") return end local aligned = aes128Cbc:decrypt(cipherBytes) if not aligned then ngx.log(ngx.WARN, "decrypt cipherBytes [" .. str.to_hex(cipherBytes) .. "] failed") return end ngx.log(ngx.NOTICE, "aligned [" .. str.to_hex(aligned) .. "], len=" .. aligned:len()) local plain local idx = aligned:find('\0') if idx then plain = aligned:sub(1, idx - 1) else plain = aligned end ngx.log(ngx.NOTICE, "plain [" .. plain .. "], len=" .. plain:len()) return测试的 nginx 错误日志:
2017/08/07 15:17:55 [notice] 34632#0: *21 [lua] aescbc.lua:22: aligned [7573722f7061737377644062697a64623a3132372e302e302e313a3534333200], len=32, client: 127.0.0.1, server: , request: "GET /aescbc HTTP/1.1", host: "127.0.0.1:8080" 2017/08/07 15:17:55 [notice] 34632#0: *21 [lua] aescbc.lua:32: plain [usr/passwd@bizdb:127.0.0.1:5432], len=31, client: 127.0.0.1, server: , request: "GET /aescbc HTTP/1.1", host: "127.0.0.1:8080"