感觉写这篇还挺是时候的,虽然本应该在上一篇之后就应该写这篇的。一直拖到现在,拖到了网易”被拖“。
上篇中说到使用aes加密,但是无论如何他还是很容易破解的,而且可以说无难度破解,首先如果想在传输过程中破解,就算你是传输的加密的数据,但是他只要同时劫持到你的js,看一下加密的方式,就可以反向破解出来,是没有任何难度,那么你加密不加密都是没有意义的。原因主要是因为aes本身采用的是对称加密方式,所以会产生上面的结果。所以我们使用rsa加密,但rsa加密过程计算量比较大,比较慢,可以用它来加密小量信息,所以我们可以用它来加密aes的key,然后在用aes加密,这样就算劫持到破解难度也增加到了破解rsa加密上去了,理论上还是很有难度的。如图:
从图片中就可以很明确的了解了整个过程了,其实主要还是使用aes加密,不过先用ras对aes加密的key进行传输(绿色部分)。然后就没有办法得到key,也就没有办法破解aes明文了。需要一个主意的地方就是客户端要产生一个random string,不然ras传key其实是毫无意义的。
原理其实就这么简单,代码更简单了,为了方便(懒),只描述rsa加密的部分,aes部分参考上一篇。下面上代码,客户端js,服务端用的php。
首先要生成一对秘钥:
1 2 |
openssl genrsa -out rsa_1024_priv.pem 1024 openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem |
js的ras加密使用的是jsencrypt
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function RSAEcrypt() { var publicKey ='-----BEGIN PUBLIC KEY-----\ MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDM+gXza++bxpFzZrAyCdrOBrzw\ eyvlT1CXG1gFrT/maOtw+i9ebv4fou2b6OlDC3As7JwfzhVCIjPpOYLd948wve2l\ jjdnEm1Z973bbmJUgg8JE0Ei05U8s5e4AQ3maUvcytbEQ9ulnYE2ufK2qsNZWhGd\ bILmjJJ4IPvRRDphQwIDAQAB\ -----END PUBLIC KEY-----'; var encrypt = new JSEncrypt(); encrypt.setPublicKey(publicKey); var uncrypted = 'test test'; var encrypted = encrypt.encrypt(uncrypted); return encrypted; } |
php部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$pi_key = '-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDM+gXza++bxpFzZrAyCdrOBrzweyvlT1CXG1gFrT/maOtw+i9e bv4fou2b6OlDC3As7JwfzhVCIjPpOYLd948wve2ljjdnEm1Z973bbmJUgg8JE0Ei 05U8s5e4AQ3maUvcytbEQ9ulnYE2ufK2qsNZWhGdbILmjJJ4IPvRRDphQwIDAQAB AoGALUUCz3IFJzhBo2UIgOSgSGRAkjQBy9EqkVTeqdJLjI2bggYfNBH7We1X4Nkd u0rpaWKQUI3pMAPxxw6GkpM8Mjhq7JcNJd33fbh3BZUXsj2NRrAn8psjhQS4vS6B +7NFHkO1+90PsHstv9vaomrdSqZt55pdAsHxUJKeUkEaTvECQQDqIaVt+wEdIvGk rsvblx27oKn+qJU3kQCMf8w+JtDSffG6q8rq84Agv+TyHpuvDiniiI9uN+qXmtQk Y7CVaQJFAkEA4B9ApesFuMcI7BKY7YFCWwt/WfPf8LwIySUd+FTzm6vlmdaUaE1k 7rmyHEHLb70nMcS6yhsRe5Ay08HRYpPR5wJBAMeMr8OiCFv9+XiD5oodLSFKmTjM FInMk2wsTDa4vIh7AXk5jHRd31mKVCasQcKczsQd4iltjQtz0dXGBa4CVwUCQQDV 5L28G2qgiEO5mZ4dvSjo3zYxURA+HhZ8cVIC+IBt50X+5c1JJePX+Z1EXn6bK3jG hKyHygGLXXlEo0sDu3OtAkB+TdkV2kMl9fYgpSTmZCmTyWujXlU7eyitoM4OzHgG xRnFBGxUxssonMaw5eo6SiqKU6EJlcIQm4UUF+crujzy -----END RSA PRIVATE KEY-----'; if(openssl_private_decrypt(base64_decode($content),$decrypted,$pi_key)) { echo $decrypted . "\n"; } else { echo 'error'; } |
主要是php的关于openssl的函数的使用。需要注意的是传过来的先要base64解密一下。
本打算写个详细的AES + RSA的demo呢,马上两点了,先碎吧。
参考:
使用RSA和AES加密传输数据 js到php
很高大上的样子
中间人还是可以劫持并更换 Public Key 的吧
是的,这个可能需要再额外的增加机制去解决.
求助,这个我还是没有理解,怎么回事,一个随机的字符串,用rsa公钥加密,然后再用,aes加密数据,我现在卡在怎么用aes加密呢?
大家好,我是第一个评论的。