encryption - OpenResty lua-resty-string:无法解密由 Crypto-JS 加密的密码(AES 默认)
问题描述
https://github.com/openresty/lua-resty-string
我无法解密在浏览器 Javascript/NodeJS 中使用 Crypto-JS 加密的内容:
// Encrypt
var ciphertext = CryptoJS.AES.encrypt('testingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtesting', '&&nH8P3bxk+?C4gR');
// Decrypt
var bytes = CryptoJS.AES.decrypt(ciphertext.toString(), '&&nH8P3bxk+?C4gR');
var plaintext = bytes.toString(CryptoJS.enc.Utf8);
console.log(plaintext);
我可以使用以下方法在 Java 中解密它:
Cipher.getInstance("AES/CBC/PKCS5Padding")
但是,我得到
nil
当我尝试用 resty.aes 来做这件事时。这是代码:
local aes = require "resty.aes"
local cipher = aes.cipher(256)
local aes_256_cbc_md5 = aes:new('&&nH8P3bxk+?C4gR', nil, cipher)
local cipherText = 'U2FsdGVkX1859eIyt4M7VHNBl9BGMdsemPYAADKmqs9sltwKINfzVMci0Vw1NLr73Iti67zQ0+JoqVcL59Gcp+4R5NY6wg2n3r0wqLcQRc7PkIGpgup1UJp4DzhXSIGHz08Eu/nEbt3jAh3S4GVUoVFbXLluf/BvedTGdsqcN2EPL9S/WQOc5QDyl9OQjpBl+QS56nWL0DO6iR/6CIoEuQ+zC/7KTpBw2jQf8sxuDNptZzwKLlDi2sWSaeCkvPj+m8zheAlnZzVc+L5JeLdcx7WkIRQImNs9P5bkhXmiK2nZnw4yco3QHbzRkRBJiB3HgdYDauHsuKmR21zv9VLjAcGTrZjiUbtrBfuTRawKOiAFm599Inbq+Ugu9n4RelQ2CTdxwDfe3ZE3kscP3dyAmg=='
ngx.say(aes_256_cbc_md5:decrypt(cipherText))
服务器端解密需要更改什么?
解决方案
首先,您需要将 base64 编码的加密数据解码为字节。
其次,您的加密数据按照此处所述进行加盐和存储:
文件有一个 8 字节的签名,后跟一个 8(?) 字节的 salt。加盐之后是加密数据。
文件以 8 字节签名开头:ASCII 字符“Salted__”。
因此,您应该从“OpenSSL salted format”-ted 字符串 ( ) 中提取盐和实际加密数据Salted__{salt}{data}
:
-- aes_demo.lua
local aes = require "resty.aes"
local encrypted = ngx.decode_base64('U2FsdGVkX1859eIyt4M7VHNBl9BGMdsemPYAADKmqs9sltwKINfzVMci0Vw1NLr73Iti67zQ0+JoqVcL59Gcp+4R5NY6wg2n3r0wqLcQRc7PkIGpgup1UJp4DzhXSIGHz08Eu/nEbt3jAh3S4GVUoVFbXLluf/BvedTGdsqcN2EPL9S/WQOc5QDyl9OQjpBl+QS56nWL0DO6iR/6CIoEuQ+zC/7KTpBw2jQf8sxuDNptZzwKLlDi2sWSaeCkvPj+m8zheAlnZzVc+L5JeLdcx7WkIRQImNs9P5bkhXmiK2nZnw4yco3QHbzRkRBJiB3HgdYDauHsuKmR21zv9VLjAcGTrZjiUbtrBfuTRawKOiAFm599Inbq+Ugu9n4RelQ2CTdxwDfe3ZE3kscP3dyAmg==')
local salt = encrypted:sub(9, 16) -- skip first 8 bytes, get salt value (8 bytes)
local data = encrypted:sub(17) -- rest of data is actual encrypted data
local cipher = aes.cipher(256)
local aes_256_cbc_md5 = aes:new('&&nH8P3bxk+?C4gR', salt, cipher)
ngx.say(aes_256_cbc_md5:decrypt(data))
$ resty aes_demo.lua
testingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtestingtesting
推荐阅读
- twilio - 如何从 Twilio Sandbox 在我的应用程序中捕获 WhatsAapp 消息
- azure - 使用 Azure 存储资源管理器查询将实体数据更新到 Azure 存储表
- c# - 如何在 C# 中使用文本框搜索列表视图的项目
- android - 片段中的 OnClickListener 不起作用。从片段到活动的意图
- angularjs - Laravel 5 + AngularJS 上的 CSRF 令牌
- python - Django:“设置”对象没有属性
- sql-server - Azure SQL 数据库 - 在存储过程中获取文件内容的正确方法
- mysql - 使用sql commit的正确方法
- ios - 即使调用了needforlayout(),也可以在单独的类中引发错误的动画自动布局约束
- php - 刀片视图渲染无限次