在设计用户注册登陆系统的时候,密码的安全传输一直是一个需要特别引起注意的地方,很多网站包括大型网站依然还是采用明文传输密码的方式,安全隐患需要注意。当然,为了防止第三人的恶意窃听,不少网站已经启用了HTTPS的加密传输。
那么,对于一些目前还不具备启用https加密传输的网站来说,飘易建议大家在前端采用js rsa加密,后端再采用PHP/JAVA进行RSA解密的方式保证密码的安全传输。
RSA是什么?
RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。目前该加密方式广泛用于网上银行、数字签名等场合。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
JS前端RSA加密需要用到第三方的加密组件JSENCRYPT:https://github.com/travist/jsencrypt 具体的大家可以到github上看下。
在开始之前,我们先要使用OpenSSL生成一对公钥、私钥,为了方便讲述,飘易还是直接提供一对生成好的公钥、私钥,至于如何生成,网上资料很多了。支付宝那里也有关于RSA密钥生成的文档:https://doc.open.alipay.com/doc2/detail?treeId=58&articleId=103242&docType=1,支付宝提供了一键生成工具
-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DLnRg3e2QdDf/m/qMvtqXi4xhw vbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfVnucVcJcxRAEcpPprb8X3hfdx KEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMnlVjDaIczKTRx+7vn2wIDAQAB AoGAZzUWajxKTZeJqh5FjBgmwZi5M7voFynZAjRWAkCkqZye0FfY7e70kA92C1AL aVqySnNr4WYZuGorEeOFGqHIv1XSowTLgfLkVBZ/SXiep2QYJrR0YevjysvLnTfb mrdWCqWSj+0AlQg+AvDA/qtvBVMxKymbpo+4bj5H2pPPZ1ECQQDi1PwJQJBYPbpL vGmP3AmWg467tCeQ+aJGgtQTOK5BH+p0BWFVDX583R437vllkKI8EXgZfqQfsQcj 7XUAXyZVAkEA2SyFbO8roH9JLrEoxxKGeiGZvhPfNl9nXLhX0OFS0ywQaVBJno39 9W5bX5iP5Jzeb3UWsZ/TxzhGc/b4WjAlbwJBAOFuIn1feRT5Y+hY++BJIg4/+N57 EMd4ENpas0HXFvcKLQvZPP42Rvr5FksoaRuTPmjMQ7uyrJICccI3AAy6g3ECQQDE AyH9+zRmLNxRj0advsOvUcpgu7DYc21oS12/Qs+tl3TMiNGZkNDphwxjkOA217sP 4B92fCn6AnncSslHJXNzAkBo6ujxqIfrZMOG3ON9nXxkWlq39GFS6CzXWscHA3Xz FMVT1WWU3FR2Kf2QSKiMGv02YcI2xfowim3JnT6600N0 -----END RSA PRIVATE KEY-----
公钥:
-----BEGIN PUBLIC KEY----- MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DL nRg3e2QdDf/m/qMvtqXi4xhwvbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfV nucVcJcxRAEcpPprb8X3hfdxKEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMn lVjDaIczKTRx+7vn2wIDAQAB -----END PUBLIC KEY-----
JS前端的加密方法:
var pubkey='-----BEGIN PUBLIC KEY-----'; pubkey+='MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DL'; pubkey+='nRg3e2QdDf/m/qMvtqXi4xhwvbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfV'; pubkey+='nucVcJcxRAEcpPprb8X3hfdxKEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMn'; pubkey+='lVjDaIczKTRx+7vn2wIDAQAB'; pubkey+='-----END PUBLIC KEY-----'; // 利用公钥加密 var encrypt = new JSEncrypt(); encrypt.setPublicKey(pubkey); var encrypted = encrypt.encrypt(JSON.stringify({"encrypt": "yes", "password": $("#password").val()})); $('#input').val(encrypted);
前端页面上对应的input输入框为:
密码:<input name="password" id="password"><br> 加密后的密文(base64):<br> <textarea id="input" name="input" type="text" rows=6 cols=70></textarea><br/> <input id="testme" type="button" value="加密"/><br/>
然后后端收到前端提交的数据,利用RSA私钥进行解密,我们以PHP举例来说:
<?php //rsa 私钥 $private_key='-----BEGIN RSA PRIVATE KEY----- MIICXQIBAAKBgQDAbfx4VggVVpcfCjzQ+nEiJ2DLnRg3e2QdDf/m/qMvtqXi4xhw vbpHfaX46CzQznU8l9NJtF28pTSZSKnE/791MJfVnucVcJcxRAEcpPprb8X3hfdx KEEYjOPAuVseewmO5cM+x7zi9FWbZ89uOp5sxjMnlVjDaIczKTRx+7vn2wIDAQAB AoGAZzUWajxKTZeJqh5FjBgmwZi5M7voFynZAjRWAkCkqZye0FfY7e70kA92C1AL aVqySnNr4WYZuGorEeOFGqHIv1XSowTLgfLkVBZ/SXiep2QYJrR0YevjysvLnTfb mrdWCqWSj+0AlQg+AvDA/qtvBVMxKymbpo+4bj5H2pPPZ1ECQQDi1PwJQJBYPbpL vGmP3AmWg467tCeQ+aJGgtQTOK5BH+p0BWFVDX583R437vllkKI8EXgZfqQfsQcj 7XUAXyZVAkEA2SyFbO8roH9JLrEoxxKGeiGZvhPfNl9nXLhX0OFS0ywQaVBJno39 9W5bX5iP5Jzeb3UWsZ/TxzhGc/b4WjAlbwJBAOFuIn1feRT5Y+hY++BJIg4/+N57 EMd4ENpas0HXFvcKLQvZPP42Rvr5FksoaRuTPmjMQ7uyrJICccI3AAy6g3ECQQDE AyH9+zRmLNxRj0advsOvUcpgu7DYc21oS12/Qs+tl3TMiNGZkNDphwxjkOA217sP 4B92fCn6AnncSslHJXNzAkBo6ujxqIfrZMOG3ON9nXxkWlq39GFS6CzXWscHA3Xz FMVT1WWU3FR2Kf2QSKiMGv02YcI2xfowim3JnT6600N0 -----END RSA PRIVATE KEY-----'; //从前端拿到的RSA加密数据 $es='CP51TfQsTXrkVeDxkkDJcO9YF6gHmIJfHX6GBLguYCXKl3A7SCn1zhXXUSwmj+MuIOh4HtsKLre3ukUOehU5V5cPYpkajCCQ5mRZfxdbOUEBNW/mT66RYmQ08WO4NGvIRriLx5LsGtS4VF4uE+8aM+mUvab6jOVUUFotqPTUyu4='; //私钥解密 openssl_private_decrypt(base64_decode($es),$decrypted,$private_key); echo $decrypted; $encrypt_exist=false; if(!empty($decrypted)) { $arr = json_decode($decrypted, true); if(array_key_exists("encrypt",$arr)) { if($arr['encrypt']=="yes") $encrypt_exist=true; } } if(!$encrypt_exist) die("抱歉!数据提交错误!"); //继续后续处理 var_dump($arr); ?>
参考资料:
1、Java中使用OpenSSL生成的RSA公私钥进行数据加解密