我用Node.js开发服务器,用Ionic框架开发客户端
我为客户端登录请求制作了API
当客户端请求登录时,发送加密的id和密码字符串
和服务器解密接收到的id和密码字符串并检查验证
我使用crypto-js(https://code.google.com/archive/p/crypto-js/)库进行客户端加密
客户端加密代码
var secret = 'abcdefghijklmnopqrstuvwxyz123456';
var id = "someId";
var encrypted = CryptoJS.AES.encrypt(id, password);
console.log(encrypted.toString()); // U2FsdGVkX19EfjjBwydSZL509wKl5TEX+4f3vakEejU=
对于服务器端解密,我使用节点内置加密模块
const crypto = require('crypto');
var method = 'aes256';
var secret = 'abcdefghijklmnopqrstuvwxyz123456';
var id = "U2FsdGVkX19EfjjBwydSZL509wKl5TEX+4f3vakEejU=" // suppose we received with no loss
var decipher = crypto.createDecipher(method, secret);
decipher.update(id,'base64','utf8');
var deciphered = decipher.final('utf8');
console.log(deciphered);
服务器端解密代码崩溃,错误信息在
下面crypto.js:153
var ret = this._handle.final();
^
Error: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
at Error (native)
at Decipher.Cipher.final (crypto.js:153:26)
at Object.<anonymous> (...routesindex.js:33:27)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
at Object.<anonymous> (...app.js:18:14)
at Module._compile (module.js:409:26)
at Object.Module._extensions..js (module.js:416:10)
at Module.load (module.js:343:32)
at Function.Module._load (module.js:300:12)
at Module.require (module.js:353:17)
at require (internal/module.js:12:17)
由于错误信息是"坏解密",所以我尝试用每个库加密相同的文本
[crypto-js]var secret = 'abcdefghijklmnopqrstuvwxyz123456';
var id = "someId";
var encrypted = CryptoJS.AES.encrypt(id, password);
console.log(encrypted.toString()); // U2FsdGVkX19EfjjBwydSZL509wKl5TEX+4f3vakEejU=
(加密模块)const crypto = require('crypto');
var method = 'aes256';
var secret = 'abcdefghijklmnopqrstuvwxyz123456';
var id = "someId"
var cipher= crypto.createCipher(method, secret);
cipher.update(id,'base64','utf8');
var ciphered = decipher.final('utf8');
console.log(ciphered.toString()); // WAsd61C2bfG7UbO5STo13A==
我发现图书馆的结果是不同的
plain text : 'someId'
crpyto-js : 'U2FsdGVkX19EfjjBwydSZL509wKl5TEX+4f3vakEejU='
crpyto module : 'WAsd61C2bfG7UbO5STo13A=='
我试图理解每个库的源代码
但是它太复杂了,所以我看不懂
我想知道每个库的加密工作原理以及导致不同结果的原因
您正在使用两个不同的系统,它们可能具有不同的默认值。不要依赖默认值,而是显式地指定两边的所有内容都相同。如果最小的东西不匹配,加密货币就会失败。您需要指定所使用的字符到字节映射、加密模式、IV(如果需要)、密钥和填充方法。
不同的输出是不同的长度,所以最初我怀疑填充是首先要看的。将两边都设置为pkcs# 7填充,看看是否有帮助。
为进一步诊断,检查key和IV是否字节对字节两边相同。
所有参数必须指定且正确。不要依赖默认值,它们依赖于实现,并且在不同的实现之间非常重要。
一般使用:
-
CBC模式带有随机iv,在加密时创建一个随机iv,将其加到加密数据前用于解密。对于AES, iv应该是16字节,即块大小。不要使用ECB模式,这是不安全的,见ECB模式,向下滚动到企鹅。
-
pkcs# 7填充(有时称为pkcs# 5)。这是必需的,因为AES是块密码,输入和输出必须是块大小的精确倍数。此填充将在加密时自动添加,在解密时自动删除。
-
确保iv和key 完全正确的尺寸
-
调试时以十六进制显示所有输入输出。在调试期间,在加密和解密之前和之后转储所有输入和输出可能会很有帮助。十六进制允许一个人看到每个字节,Base64将3个字节组合成4个字节,使其更难以理解。
当所有这些都完全相同时,输出也将完全相同。