emu in blogjava

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

          <!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>

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


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


          (第一次加密錯了,第二次對了)
          posted on 2017-06-12 17:48 emu 閱讀(1249) 評論(0)  編輯  收藏

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


          網(wǎng)站導航:
           
          主站蜘蛛池模板: 德清县| 无为县| 屯留县| 周宁县| 静乐县| 徐闻县| 彭水| 安新县| 公安县| 保靖县| 拜城县| 林口县| 密山市| 汤原县| 梅州市| 罗源县| 漳平市| 土默特右旗| 犍为县| 四会市| 建阳市| 乐东| 玉门市| 齐河县| 虎林市| 江永县| 鄂托克前旗| 嘉祥县| 万年县| 长兴县| 凤山县| 伊宁县| 临清市| 琼海市| 和静县| 鹤岗市| 曲阜市| 桂林市| 涪陵区| 习水县| 察哈|