前端加密控件CryptoJS的使用

      在做Web项目的过程中,由于要通过页面上传多个文件,而我们在后台计算过程中仅需要文件的哈希值,为了节省带宽,我们选择在前端页面进行文件哈希值计算,然后把哈希值传递给后台,这样避免了传递大量文件。    

      CryptoJS为JavaScript库,提供了各种各样的加密算法,包括MD5、SHA1、SHA256、AES、Rabbit等

      (一)CryptoJS Github地址:https://github.com/brix/crypto-js
      (二)使用方法
        1)引入核心js文件,需要使用的算法对应的js文件
        2)cryptojs支持对字符串计算,或者对WordArray类型(CryptoJS自己封装的数据类型)值的计算,如果需要对文件进行哈希值计算,则使用WordArray方式。
        示例:
       //String
       var sha1Encrypt = CryptoJS.SHA1("Message");
        var sha256Encrypt = CryptoJS.SHA256("Message");
       //WordArray
       var wordArray = CryptoJS.enc.Utf8.parse("cfca1234");
       var base64 =  CryptoJS.enc.Base64.stringify(wordArray);
      3)对文件计算示例
       //对文件计算哈希值:    
      function arrayBufferToWordArray(ab) {
              var i8a = new Uint8Array(ab);
              var a = [];
              for (var i = 0; i < i8a.length; i += 4) {
                  a.push(i8a[i] << 24 | i8a[i + 1] << 16 | i8a[i + 2] << 8 | i8a[i + 3]);
             }
                  return CryptoJS.lib.WordArray.create(a, i8a.length);
     }
                
     function uploadFile(){
             var dat = $("#testfile")[0].files[0];
             var reader = new FileReader();
             reader.readAsArrayBuffer(dat);
             reader.onload = function(evt){
                   console.log(evt.target.result);
                   var fileString = evt.target.result;
                   var wordArray = arrayBufferToWordArray(fileString);
                   var hash = CryptoJS.SHA256(wordArray).toString(CryptoJS.enc.Hex);
                   $("#file256").text(hash);
            }
      }
 
     4)CryptoJS update
     但是上面的方式会把文件一次性读入内存,非常耗浏览器内存,当文件比较大时,容易导致浏览器崩溃,因此采用了CryptoJS update的方式,增量计算哈希值
function loadFile(fileId,hashId){
     var contractFile = $("#"+fileId)[0].files[0];
     var reader = new FileReader();
     var blobSlice = File.prototype.mozSlice || File.prototype.webkitSlice || File.prototype.slice;
     // 指定文件分块大小(2M)
    var chunkSize = 6 * 1024 * 1024;
    // 计算文件分块总数
    var chunks = Math.ceil(contractFile.size / chunkSize);
    // 指定当前块指针
    var currentChunk = 0;
   
    var hasher = CryptoJS.algo.SHA256.create();
    // FileReader分片式读取文件
    // 计算开始读取的位置
    var start = currentChunk * chunkSize;
    // 计算结束读取的位置
    var end = start + chunkSize >= contractFile.size ? contractFile.size : start + chunkSize;
    reader.readAsArrayBuffer(blobSlice.call(contractFile, start, end));
    reader.onload = function(evt){
           var fileStr = evt.target.result;
           var tmpWordArray = arrayBufferToWordArray(fileStr);
           hasher.update(tmpWordArray);
           currentChunk += 1;
           fileStr = null;
           tmpWordArray = null;
           // 判断文件是否都已经读取完
        if (currentChunk < chunks) {
            // 计算开始读取的位置
            var start = currentChunk * chunkSize;
            // 计算结束读取的位置
            var end = start + chunkSize >= contractFile.size ? contractFile.size : start + chunkSize;
            reader.readAsArrayBuffer(blobSlice.call(contractFile, start, end));
        }
     }
     reader.onloadend = function(){
           contractFile = null;
           var fileobj = document.getElementById(fileId);
         if(fileobj.outerHTML){
           fileobj.outerHTML = fileobj.outerHTML;
         }
         CollectGarbage();
         var hash = hasher.finalize();
 
         $("#"+hashId).val(hash);
         hasher = null;
 
         blobSlice = null;
         reader = null;
         hash = null;
         CollectGarbage();
     }
}
     
(三)总结
parse和stringify
var wordArray = CryptoJS.enc.Utf8.parse(utf8String);
var wordArray = CryptoJS.enc.Latin1.parse(latin1String);
var wordArray = CryptoJS.enc.Hex.parse(hexString);
var wordArray = CryptoJS.enc.Base64.parse(base64String);
 
var utf8String = CryptoJS.enc.Utf8.stringify(wordArray);
var latin1String = CryptoJS.enc.Latin1.stringify(wordArray);
var hexString = CryptoJS.enc.Hex.stringify(wordArray);
var base64String = CryptoJS.enc.Base64.stringify(wordArray);
 
消息摘要算法
var hash = CryptoJS.MD5(message);
var hash = CryptoJS.MD5(wordArray);
......
 
update调用方式
var hasher = CryptoJS.algo.SHA256.create();
hasher.reset();
hasher.update('message');
hasher.update(wordArray);
var hash = hasher.finalize();
var hash = hasher.finalize('message');
var hash = hasher.finalize(wordArray);
 
 
posted @ 2019-08-29 14:18  成长的程序员  阅读(24043)  评论(6编辑  收藏  举报