emu in blogjava

            BlogJava :: 首頁(yè) :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
            171 隨筆 :: 103 文章 :: 1052 評(píng)論 :: 2 Trackbacks
          今天下午和一個(gè)妹子聊到在前端做AES加密,妹子說(shuō)有一些開源的庫(kù),我想webcrypto提出來(lái)這么多年,應(yīng)該主流瀏覽器很多也應(yīng)該有原生的支持了吧?寫個(gè)加測(cè)試頁(yè)面試試看:

          <!DOCTYPE html>
          <html>
              <head>
                  <META NAME="Author" CONTENT="emu">
                  <META NAME="Keywords" CONTENT="webcrypto AES-CBC AES-GCM">
              </head>
              <body>
                  <div id="out"></div>
                  <script type="text/javascript">
                      
          function output(sign) {
                          document.getElementById(
          "out").innerHTML += sign + "<br>";
                      }
                      
          function bufferToHex(b){
                          
          var dataview = new DataView(b);
                          result 
          = "";
                          
          for (var i = 0; i < b.byteLength; i += 4) {
                              tmp 
          = dataview.getUint32(i).toString(16);
                              result 
          += (tmp.length == 8 ? "" : "0"+ tmp;
                          }
                          
          return result;
                      }

                      
          function bufferToString(b){
                          
          //new TextDecoder().decode(b)
                          var hex=bufferToHex(b);
                          
          var result=unescape(hex.replace(/(..)/g,"%$1"));
                          
          return result;
                      }
                      
          function stringToBuffer(s){
                          
          //new TextEncoder().encode(s);
                           var a = s.split("");
                           
          for (var i = 0; i < a.length; i++) {
                                  a[i] 
          = a[i].charCodeAt(0)
                           };
                           
          var result = new Uint8Array(a);
                           
          return result;
                      }


                  
          var textToBeEncrypted = 'Hello World!';
                  
          var bufferToBeEncrypted=stringToBuffer(textToBeEncrypted);
                  
          var bufferToBeDecrypted;
                  
          var pwd="let me try this password"
                  
          var password = stringToBuffer(pwd);
                  
          var sAlg="AES-CBC";//AES-GCM部分瀏覽器不支持
                  var c = window.crypto || window.msCrypto;
                  
          var subtle = c.subtle || c.webkitSubtle;
                  
          var iv = c.getRandomValues(new Uint8Array(16));
                  
          var alg = { name: sAlg, iv: iv };
                  
          var op=c.subtle.digest('SHA-256', password)
                  
          var encryptKey,decryptKey,hash;
                  
          if(("then" in op)){
                      op.then(
          function(buffer){
                          hash
          =buffer;
                          c.subtle.importKey('raw', hash, alg, 
          false, ['encrypt']).then(function(buffer){
                              encryptKey
          =buffer;
                              c.subtle.importKey('raw', hash, alg, 
          false, ['decrypt']).then(function(buffer){
                              decryptKey
          =buffer;
                              doEncrypt(alg,encryptKey);
                              })
                          })
                      });
                  }
          else{
                      op.oncomplete
          =function(e){
                          
          var hash=e.target.result;
                          
          var op=c.subtle.importKey('raw', hash, alg, false, ['encrypt']);
                          op.oncomplete
          =function(e){
                              encryptKey
          =e.target.result;
                              op
          =c.subtle.importKey('raw', hash, alg, false, ['decrypt']);
                              op.oncomplete
          =function(e){
                                  decryptKey
          =e.target.result;
                                  encryptWithCryptoOperation(alg,encryptKey);
                              }
                          }
                      }
                  }
                  
          function doEncrypt(alg,encryptKey){
                      
          var op = c.subtle.encrypt(alg, encryptKey, bufferToBeEncrypted);
                      op.then(
          function(buffer){
                              bufferToBeDecrypted
          =buffer;
                              output(
          "pwd: <b><i>"+pwd+"</i></b> alg:<b>"+sAlg+"</b> <br>encrypt("+textToBeEncrypted + ")="+ bufferToHex(buffer));
                              doDecrypt(alg,decryptKey);
                          })
                  }

                  
          function doDecrypt(alg,decryptKey){
                      
          var op = c.subtle.decrypt(alg, decryptKey, bufferToBeDecrypted);
                      op.then(
          function(buffer){
                          output(
          "pwd:<b><i>"+pwd+"</i></b>  alg:<b>"+sAlg+"</b> <br>decrypt("+bufferToHex(bufferToBeDecrypted) + ")="+ bufferToString(buffer));
                      })
                  }

                  
          function encryptWithCryptoOperation(alg,encryptKey){
                      
          var op = c.subtle.encrypt(alg, encryptKey);
                      op.onerror
          =function(e){output(sAlg+"  unsupported")}
                      op.process(bufferToBeEncrypted);
                      op.oncomplete
          =function(e){
                          bufferToBeDecrypted
          =e.target.result
                              output(
          "pwd: <b><i>"+pwd+"</i></b> alg:<b>"+sAlg+"</b> <br>encrypt("+textToBeEncrypted + ")="+ bufferToHex(bufferToBeDecrypted));
                          
          //decryptWithCryptoOperation(alg,decryptKey)
                          setTimeout(decryptWithCryptoOperation,0,alg,decryptKey)
                      }
                      op.finish();
                  }        
                  
          function decryptWithCryptoOperation  (alg,decryptKey){
                      
          var op = c.subtle.decrypt(alg, decryptKey);
                      op.onerror
          =function(e){(sAlg+"  unsupported")}
                      op.process(bufferToBeDecrypted);
                      op.oncomplete
          =function(e){
                          
          if(!e.target.result){
                              output(
          "IE is crazy!<br>");
                              encryptWithCryptoOperation(alg,encryptKey)
                          }
          else
                              output(
          "pwd:<b><i>"+pwd+"</i></b>  alg:<b>"+sAlg+"</b> <br>decrypt("+bufferToHex(bufferToBeDecrypted) + ")="+ bufferToString(e.target.result));
                      }
                      op.finish();
                  }
                  
          </script>
              </body>
          </html>

          測(cè)試下來(lái)感覺(jué)各個(gè)瀏覽器支持程度還是參差不齊,IE11和Edge都是不同的實(shí)現(xiàn)方式,IE11甚至還會(huì)隨機(jī)出現(xiàn)oncomplete的時(shí)候result數(shù)據(jù)都還沒(méi)有ready的情況,甚至于有的時(shí)候完全相同的入?yún)ⅲòS機(jī)數(shù)也相同)加密出來(lái)的結(jié)果居然會(huì)不同,也就是說(shuō)有的時(shí)候加密算法自己會(huì)加密錯(cuò),出來(lái)的結(jié)果根本就無(wú)法被正確解密,實(shí)在是個(gè)半成品:


          (第一次加密錯(cuò)了,第二次加密對(duì)了解密錯(cuò)了,第三次終于加解密都對(duì)了)


          (第一次加密錯(cuò)了,第二次對(duì)了)
          posted on 2017-06-12 17:48 emu 閱讀(1238) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 清远市| 永嘉县| 当涂县| 云南省| 肇源县| 新巴尔虎右旗| 宝山区| 洪泽县| 扎囊县| 隆回县| 信宜市| 哈巴河县| 峨眉山市| 通州市| 遂平县| 德阳市| 福泉市| 黄浦区| 正宁县| 深泽县| 奈曼旗| 左云县| 黑龙江省| 广德县| 航空| 麦盖提县| 昂仁县| 凌云县| 灌云县| 客服| 湘潭县| 固阳县| 柳江县| 成安县| 夏邑县| 景东| 永春县| 中山市| 西和县| 鄂托克前旗| 恩平市|