会写hello world 的都应该知道明文传输敏感信息是非常不好的一个习惯。这两天要做个东西,使用的是AES加密算法,但是遇到了一些坑。这里总结整理一下。
前端是用js,后台用php,分别使用的是:cryptoJs,mcrypt。
使用aes加密,所以考虑的加密解密一致性需要考虑的就有mode,和padding。
先来看cryptoJs支持的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
CryptoJS supports the following modes: CBC (the default) CFB CTR OFB ECB And CryptoJS supports the following padding schemes: Pkcs7 (the default) Iso97971 AnsiX923 Iso10126 ZeroPadding NoPadding |
php mode支持:
One of the MCRYPT_MODE_modename
constants, or one of the following strings: “ecb”, “cbc”, “cfb”, “ofb”, “nofb” or “stream”.
padding: 模式有null pading (zero padding )和 Pkcs7 默认的为null padding.
所以最后统一使用的是AES/CBC/zeroPadding
除了上面这些还有个就是key,对于js来说,可以应为16或者32位,会根据位数判断使用aes-256(default)还是aes-128。相对应的就是加密之后的结果为16为还是32位。因为MCRYPT使用的是MCRYPT_RIJNDAEL_128所以js也要使用128的才可以。(MCRYPT_RIJNDAEL_256并不是aes-256,其实可以不用MCRYPT使用openssl扩展)
为了保证js使用的也是128bit的,所以需要先utf8转码一下就会是使用128的。下面直接上代码。
1 2 3 4 5 6 7 8 9 10 11 |
// ase Encrypt javascript function encrypt() { var key_hash = CryptoJS.MD5('str');//.toString(); var key = CryptoJS.enc.Utf8.parse(key_hash); // 必须16位(128bit)所以可以先md5一下 var iv = CryptoJS.enc.Utf8.parse('1234567812345678'); var encrypted = CryptoJS.AES.encrypt('str', key, {iv:iv, mode:CryptoJS.mode.CBC, padding:CryptoJS.pad.ZeroPadding}); console.log(encrypted.toString()); //cYPVoNnu+Y1ZGMve+HAW4A== } encrypt(); |
1 2 3 4 5 6 7 8 9 |
function cryption() { $iv = "1234567812345678"; $privateKey = md5("str"); //解密 $encryptedData = base64_decode("cYPVoNnu+Y1ZGMve+HAW4A=="); $decrypted = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $privateKey, $encryptedData, MCRYPT_MODE_CBC, $iv); echo($decrypted); } |
但是但是但是毕竟aes加密是对称密钥加密而且前端到php的话,一定会在前端方面把key,vi暴露出来,如果想做安全一点就是前端和后台是用同一个算法来生成key,使其不是唯一。然后不停的交换秘钥,这种情况下用户只有分析js秘钥生成算法和密文信息才有可能解密出来。
但是其实仔细想一下,这种东西相对于明文来说只是对破解难度稍微增加了一点难度而已,对于前端这种应用场景安全性并不是太有用。
所以有一种方式就是使用非对称加密算法(例如rsa)来进行加密传输,但这个有个确定加密效率低慢,或者我们使用https传输,另一个就是利用aes加密效率高和非对称加密来传递秘钥相结合,这个可能是一种稍微折中的方案。具体实施,请见下一篇
其实不论如何非对称加密也好,对称加密也要,我们都要有相对信任的”人“,查资料别人说总要有一个100%信任的第三方(如https第三方证书),但是我想是不是可以采用分而治之的方式,对每个“人”都只信任一点,这样就算一方出问题也不会完全暴露。
参考:填充模式
“使用AES加密传输数据 js到php”上有 1 条回复;
评论已关闭。