今天看啥
    热点:

      天发国际娱乐官网:深入贯彻对台工作大政方针,坚持一个中国原则,维护“九二共识”共同政治基础,维护国家主权和领土完整,维护两岸关系和平发展和台海和平稳定。

      RSA非对称算法实现HTTP密码加密传输


        目前一般帐号系统,都是https来传输账户性息,申请一个https证书也不贵。但是网站的其它功能并不需要走https协议,https和http混布比较麻烦,所以决定先实现一个http协议传输RSA非对称密钥算法加密密码的方案。这样做只能说是保证不明文传密码,但是并不能防身份伪造,所以其实还是不安全的,只是目前产品能接受,算是一个过渡期吧。有需要的话还是要改成https的。

          关于rsa算法,具体参考维基百科相关的介绍。简单来说,用rsa算法产生一对公钥和私钥,通信双方A和B,A用公钥加密要发送的数据,B用私钥来解密A发过来的密文,从而获得a想要发过来的数据。保证rsa密文不容易被破解的理论依据是对极大整数做因数分解的难度非常大。

          下面具体看看实现过程。这里前端用到rsa的js实现方案jsencrpt.js ,后端用php的open_pkey_new等相关方法。

         

          1.【后端】先看php生成公钥密钥对相关代码:

      function generatePubPri() {
          $config = array("config" => '/path/to/openssl.cnf');    
          $res = openssl_pkey_new($config);    
          openssl_pkey_export($res,$pri, null, $config);    
          $d= openssl_pkey_get_details($res);    
          $pub = $d['key'];    
      
          $pubFd = fopen("pub.txt", "w");
          fwrite($pubFd, $pub);
          fclose($pubFd);
      
          $priFd = fopen("pri.txt", "w");
          fwrite($priFd, $pri);
          fclose($priFd);
      }

          这里前提是要安装openssl,php要加载openssl扩展。执行generatePubPri即可的到如下的公钥密钥对,每次执行生成的都不一样。

      [xxx@xxx makedemo]$ cat pri.txt 
      -----BEGIN RSA PRIVATE KEY-----
      MIICXQIBAAKBgQCq/8HruBYhems80BluLiiP0uUTzM/NJSFktzxA1rfzjhEg8z0W
      r0WAvIdbye2vTG0CYi6PGpjxgUkEVaaHLWEIMiA4g3TIFSUp5pmlWRpGNqilrxd4
      sXM5wzL13WkN1j6gBfZNJt62mO35A2Ubl9fbNw/YU2KNPR0+EHP0Z6agmwIDAQAB
      AoGAViPcllf3ngnDN7FE/kH2YO1GRMEp9Re9SLUdfzQrGl/4tPaTUXgdtQpDzbNd
      Lq97QnYfKiul3BLaq3pSF0p+1AUHtJby/HT1Tqz0380x9Y+QKjJErePycTs28zIq
      FXmCMnOqxhaWPB89hxCIG0g7bVt9qGRDUZGY05kMwSM9gvECQQDcWjQoBfb4IQls
      RUQlprzizQD+S4cHJdxCq5qh7TqyH1IPoHq04tQsuYFVEH2+Z0Spimz/oluNuDnJ
      NppKdJZdAkEAxqmbtzs9bPbyihb9qpsD8Sne1DIo5uRBJ7G4/RE4vazaAXX9HUIS
      HZg/To5XSGHzgQteIUXJRjpX5sYLCS8zVwJAQxElbMUb/Tu47X5LlpYgSXuSANQm
      HfPVDWnDn+NfiRVlWaJDlsivQYmYprZlP02ZJW0fbdMRwJnA5NA8t8qydQJBAKZH
      dERLW0CG+b7HO46+rPAAAbhOO5n2VuqogJOhBIMN2HL8lN0WXh9TPTm9PiUhhzTt
      lN34kV0snEJWZQpM7YUCQQCgKhoAlp4DpcYvqq569UI7IE4ZL4l9RlkiNG1UYyda
      iZoNVN7ji8K2ZvOKykJBwDeKIn4JrknUHrjZXEweRKEl
      -----END RSA PRIVATE KEY-----
      [xxx@xxx makedemo]$ cat pub.txt 
      -----BEGIN PUBLIC KEY-----
      MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq/8HruBYhems80BluLiiP0uUT
      zM/NJSFktzxA1rfzjhEg8z0Wr0WAvIdbye2vTG0CYi6PGpjxgUkEVaaHLWEIMiA4
      g3TIFSUp5pmlWRpGNqilrxd4sXM5wzL13WkN1j6gBfZNJt62mO35A2Ubl9fbNw/Y
      U2KNPR0+EHP0Z6agmwIDAQAB
      -----END PUBLIC KEY-----

          2.【前端】用公钥加密一下密码"123456"。

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>JS->jsencrypt.js RSA加密实现</title>
          <script type="text/javascript" src="jsencrypt.js"></script>
      </head>
      <body>
      <script type="text/javascript">
      var crypt = new JSEncrypt(); //新建rsa对象
      var publickey = '\
      -----BEGIN PUBLIC KEY-----\
      MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq/8HruBYhems80BluLiiP0uUT\
      zM/NJSFktzxA1rfzjhEg8z0Wr0WAvIdbye2vTG0CYi6PGpjxgUkEVaaHLWEIMiA4\
      g3TIFSUp5pmlWRpGNqilrxd4sXM5wzL13WkN1j6gBfZNJt62mO35A2Ubl9fbNw/Y\
      U2KNPR0+EHP0Z6agmwIDAQAB\
      -----END PUBLIC KEY-----\
              ';
      crypt.setPublicKey(publickey);//添加来自服务端的publickey
      var result = crypt.encrypt('123456'); //返回值为加密后的结果
      console.log(result);
      </script>
      </body>
      </html>

          在浏览器里访问后,控制台会打印出如下的加密字符串:

      SonHPbJpQBwygjZ5ZMtybfLEylnNCsd3poBsNxSt3QkUSDe+Pf7lf4JJIot9Ybd7mAXiOUgGZR7VctCSJhzzZQWNZp1or6h6dsYoFHE/dbDHIxJGcXMNfv5BqrfAMGqkQVvyrED3NHcrgXokataRJOrsU7yvKpQKW6e3j+zcZD8=
      eRA40/RbbbqtuEC10Ee3NVDsnpfgibn8nRuTaPmvXI1XjVFX8pjwtMxiuT9xaBfX8K+LI/6ccgghYyJdxjd8V+DyxBPz6/QzT3f5eoOz9ULD85r0K//BuKvuTiyQ/NajProvPN3ns6UzxECmuFg0UNtrMNkOdFRpaAtueadKJDU=
      Tqgagyx5DlDLI/tcxYsnN/3AbUPCX/EFE6yn5SoVMX3R/RQ6od6b4hT10LUctcBZ649RhHkwzxTFzIFfvbRS87OftOhebGXAP9JpN/xt9IsaXOU4wp8ZiyQKIrClnepXtRaSC10WF/ishsejgo3i7APXs7fWJiEMkoqRYwnbyPo=

           。。。。。。奇怪的是每次刷新打印的都不一样。估计都可以用的。

          3. 【后端】解密前端发送过来的密文

              解密的方法:

      /** 
       * rsa解密
       * @access public
       * @param 密文
       * @return 解密后的字符串
       */
      function decrypt($data, $privkey) {   
          if (openssl_private_decrypt(base64_decode($data), $decrypted, $privkey)){
              $data = $decrypted;
          }else { 
              $data = ''; 
          }
          return $data;
      }

      priveKey=file g et c ontents("pri.txt");  priveKey=filegetcontents("pri.txt"); data = "SonHPbJpQBwygjZ5ZMtybfLEylnNCsd3poBsNxSt3QkUSDe+Pf7lf4JJIot9Ybd7mAXiOUgGZR7VctCSJhzzZQWNZp1or6h6dsYoFHE/dbDHIxJGcXMNfv5BqrfAMGqkQVvyrED3NHcrgXokataRJOrsU7yvKpQKW6e3j+zcZD8=";
      echo decrypt(data, data, priveKey);
      echo "\n";

          最后是解密出"123456"

      [xxx@xxx makedemo]$ php rsa.php 
      123456

          试了一下另外两个密文,非常棒,发现也是可以解出"123456"。

          最后给一个完整的demo,流程如下:

         

          代码如下:

          1.submitPassword.html

      <!DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <title>JS->jsencrypt.js RSA加解密实现</title>
          <script type="text/javascript" src="jsencrypt.js"></script>
          <script type="text/javascript" src="http://www.1click-soft.com/tfgjylgw/jquery/1.9.1/jquery.min.js"></script>
      </head>
      <body>
      <script type="text/javascript">
      var PassWord = "123456";
      function myEncrypt(pass) {
          var crypt = new JSEncrypt();
          var publickey = "";
          crypt.setPublicKey(publickey);
          return crypt.encrypt(pass); 
      }
      var promise = $.ajax({
          url: "getPublicKey.php",
          method: "POST",
          dataType: "json",
          data: {}
      });
      promise.done(function(data){
          if(data.code  === 0) {
              var passWord = myEncrypt(PassWord); 
              var passPromise = $.ajax({
                  url: "recievePassword.php",
                  method: "POST",
                  dataType: "json",
                  data: {"password": passWord}
              });
              passPromise.done(function(data){
                  if(data.code === 0) {
                      console.log("submit success.");
                  }else{
                      console.log("submit failed.");
                  }
              });
              passPromise.fail(function(err){
                  console.log(err);
              });
          }else {
              console.log("submit failed.");
          }
      });
      promise.fail(function(err){
          console.log(err);
      });
      
      </script>

          2.getPublicKey.php

      function generatePubPri() {
          $config = array("config" => '/home/users/zhutianpeng/.jumbo/etc/ssl/openssl.cnf');    
          $res = openssl_pkey_new($config);    
          openssl_pkey_export($res,$pri, null, $config);    
          $d= openssl_pkey_get_details($res);    
          $pub = $d['key'];    
      
          $pubFd = fopen("pub.txt", "w");
          fwrite($pubFd, $pub);
          fclose($pubFd);
      
          $priFd = fopen("pri.txt", "w");
          fwrite($priFd, $pri);
          fclose($priFd);
      
          return $pub;
      }
      
      $publicKey = generatePubPri();
      $data = array("code" => 0,
          "msg" => "success", 
          "data" => array("pubkey" => $publicKey));
      echo json_encode($data);

          3.recievePassword.php

      $passWord = $_POST['password'];
      $ret = array();
      if(!empty($passWord)) {
          $ret['code'] = 0;
          $ret['msg'] = "success";
      }else {
          $ret['code'] = 1;
          $ret['msg'] = "not recieved a password";
      }
      echo json_encode($ret);

        [完]

      www.1click-soft.comtruehttp://www.1click-soft.com/Linux/1304175.htmlTechArticleRSA非对称算法实现HTTP密码加密传输 目前一般帐号系统,都是https来传输账户性息,申请一个https证书也不贵。但是网站的其它功能并不需要...

      相关文章

        暂无相关文章

      帮客评论

      视觉看点
      百度 360 搜狗