使用 RSA 和 AES 加密传输数据 js 到 php(前端非对称加密)

7,409 阅读2分钟

感觉写这篇还挺是时候的,虽然本应该在上一篇之后就应该写这篇的。一直拖到现在,拖到了网易”被拖“。

上篇中说到使用aes加密,但是无论如何他还是很容易破解的,而且可以说无难度破解,首先如果想在传输过程中破解,就算你是传输的加密的数据,但是他只要同时劫持到你的js,看一下加密的方式,就可以反向破解出来,是没有任何难度,那么你加密不加密都是没有意义的。原因主要是因为aes本身采用的是对称加密方式,所以会产生上面的结果。所以我们使用rsa加密,但rsa加密过程计算量比较大,比较慢,可以用它来加密小量信息,所以我们可以用它来加密aes的key,然后在用aes加密,这样就算劫持到破解难度也增加到了破解rsa加密上去了,理论上还是很有难度的。如图:

从图片中就可以很明确的了解了整个过程了,其实主要还是使用aes加密,不过先用ras对aes加密的key进行传输(绿色部分)。然后就没有办法得到key,也就没有办法破解aes明文了。需要一个主意的地方就是客户端要产生一个random string,不然ras传key其实是毫无意义的。

原理其实就这么简单,代码更简单了,为了方便(懒),只描述rsa加密的部分,aes部分参考上一篇。下面上代码,客户端js,服务端用的php。

首先要生成一对秘钥:

openssl genrsa -out rsa_1024_priv.pem 1024
openssl rsa -pubout -in rsa_1024_priv.pem -out rsa_1024_pub.pem
js的ras加密使用的是jsencrypt

js的ras加密使用的是jsencrypt

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部分


$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呢,马上两点了,先碎吧。

参考:

js rsa加密库

php openssl