p2p网站开发维护,重庆王网站制作,深圳网络推广案例,开发网站公司门户网站很多人对于AES加密并不是很了解#xff0c;导致互相之间进行加密解密困难。 本文用简单的方式来介绍AES在使用上需要的知识#xff0c;而不涉及内部算法。最后给出例子来帮助理解AES加密解密的使用方法。
AES的麻烦
相比于其他加密#xff0c;AES加密似乎模式很多#xf…很多人对于AES加密并不是很了解导致互相之间进行加密解密困难。 本文用简单的方式来介绍AES在使用上需要的知识而不涉及内部算法。最后给出例子来帮助理解AES加密解密的使用方法。
AES的麻烦
相比于其他加密AES加密似乎模式很多包括ECB、CBC等等等等每个模式又包括IV参数和Padding参数并且不同语言对AES加密的库设计有区别。这些导致AES加密在不同人之间联调会很麻烦。
AES属于块加密
不难理解对越长的字符串进行加密代价越大所以通常对明文进行分段然后对每段明文进行加密最后再拼成一个字符串。块加密的一个要面临的问题就是如何填满最后一块所以这就是PADDING的作用使用各种方式填满最后一块字符串所以对于解密端也需要用同样的PADDING来找到最后一块中的真实数据的长度。
加密模式
AES分为几种模式比如ECBCBCCFB等等这些模式除了ECB由于没有使用IV而不太安全其他模式差别并没有太明显大部分的区别在IV和KEY来计算密文的方法略有区别。具体可参考 wiki说明 另外AES分为AES128AES256等表示期待秘钥的长度比如AES256秘钥的长度应该是256/8的32字节一些语言的库会进行自动截取让人以为任何长度的秘钥都可以。而这其实是有区别的。
IV的作用
IV称为初始向量不同的IV加密后的字符串是不同的加密和解密需要相同的IV既然IV看起来和key一样却还要多一个IV的目的对于每个块来说key是不变的但是只有第一个块的IV是用户提供的其他块IV都是自动生成。 IV的长度为16字节。超过或者不足可能实现的库都会进行补齐或截断。但是由于块的长度是16字节所以一般可以认为需要的IV是16字节。
PADDING
AES块加密说过PADDING是用来填充最后一块使得变成一整块所以对于加密解密两端需要使用同一的PADDING模式大部分PADDING模式为PKCS5, PKCS7, NOPADDING。
加密解密端
所以在设计AES加密的时候
对于加密端应该包括加密秘钥长度秘钥IV值加密模式PADDING方式。对于解密端应该包括解密秘钥长度秘钥IV值解密模式PADDING方式。
Nodejs实现
这里使用Nodejs的cryptojs库模拟AES加密解密
var crypto require(crypto);var algorithmaes-256-cbc;
var key new Buffer(aaaabbbbccccddddeeeeffffgggghhhh);
var iv new Buffer(1234567812345678);
function encrypt(text){var ciphercrypto.createCipheriv(algorithm,key,iv);cipher.update(text,utf8);return cipher.final(base64);
}
function decrypt(text){var ciphercrypto.createDecipheriv(algorithm,key,iv);cipher.update(text,base64);return cipher.final(utf8);
}var textni你好hao;
var encodedencrypt(text)
console.log(encoded);
console.log(decrypt(encoded))结果如下
WfH4hzIc3dc0pjxa9V/RgQ
ni你好haonodejs自带的并不能自动配置padding等参数演示起来并不方便。 于是使用另一个框架crypto-js的nodejs库实现和之前完全相同的版本
var CryptoJS require(crypto-js);
var key aaaabbbbccccddddeeeeffffgggghhhh;
var iv 1234567812345678;function encrypt(text){return CryptoJS.AES.encrypt(text,CryptoJS.enc.Utf8.parse(key),{iv:CryptoJS.enc.Utf8.parse(iv),mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7})
}function decrypt(text){var result CryptoJS.AES.decrypt(text,CryptoJS.enc.Utf8.parse(key),{iv:CryptoJS.enc.Utf8.parse(iv),mode:CryptoJS.mode.CBC,padding:CryptoJS.pad.Pkcs7})return result.toString(CryptoJS.enc.Utf8)
}var textni你好hao;
var encodedencrypt(text)
console.log(encoded.toString());
console.log(decrypt(encoded))现在aes的参数都变成可配置的接下来验证一下之前对AES的理解。
改变IV的长度发现当IV大于16字节的时候不管16字节之后的是什么都不影响加密结果应该是种自动截取机制(nodejs原生库IV不是16字节就会报错改变IV的长度当IV小于16字节还可以成功加密可能是自动补齐机制加密IV和解密IV不同的时候并不影响解密是否成功但是解密的结果有差别比如将解密的IV变成1234567813345678则解密结果变为ni你好ho 修改padding加密解密的padding换成NoPadding发现解密之后生成utf8字符串出错经过多次尝试加密为Pkcs7和ZeroPadding时加密后的字符串变化显著这时解密用任何padding模式都可以成功解密。
ni你好hao经过Pkcs7后输出为
WfH4hzIc3dc0pjxa9V/RgQnopadding后输出为
OtSNypfx1SF6C2Ezeropadding后输出为
OtSNypfx1SF6C2GfyXMidAPkcs7的结果和其他结果相差很大很难相信其padding是补充最后一块 有趣的是Pkcs7的结果和zeropadding的结果通过同样的解密设置能解出同样的字符串ni你好hao
总结
AES加密解密的秘钥有一对一个是IV一个是KEY并且他们的长度都有严格要求。 Padding的作用似乎不只是补齐最后如果自己什么都对但是加密失败可以尝试不同Padding