emu in blogjava

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

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


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


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

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 溧水县| 嵊州市| 平武县| 津南区| 安顺市| 余庆县| 大名县| 巢湖市| 普兰县| 柘荣县| 榆林市| 科技| 乌兰察布市| 健康| 南投县| 孙吴县| 石林| 马关县| 德州市| 牡丹江市| 莲花县| 新巴尔虎右旗| 瑞丽市| 长沙市| 大石桥市| 乐昌市| 浦江县| 博客| 衡阳市| 安康市| 瑞昌市| 清镇市| 新和县| 临海市| 通城县| 长顺县| 西乡县| 基隆市| 灵寿县| 北京市| 格尔木市|