• [转] js在浏览器端对二进制流进行AES加密和解密


    开始解密

    简单了解一下所用的的AES加密算法,我们用的是AES的CFB加密方式,服务端会提供给我一个key和iv的二进制字节串。密文也是二进制字节串。

    我用的加密/解密插件: crypto-js

    一般的应用场景下,key和iv以及密文都是字符串,按照网上的教程基本上很快就能搞出来了。
    这里只简述一下key、iv、密文均为二进制字节串的情况下怎么用crypto-js来解密。

    需要引进下面几个js:

    <script src="aes.js"></script>
    <script src="mode-cfb.js"></script>
    <script src="pad-nopadding.js"></script>
    <script src="lib-typedarrays.js"></script>
    <script src="enc-base64.js"></script>
    <script src="js/lib/enc-u8array.js"></script> <!-- 注意一下这个,并不在插件源文件中 -->

    注意一下最后一个文件,是我从网上摘录的,在插件源文件中是没有的。内容如下:

    CryptoJS.enc.u8array = {
    /**
    * Converts a word array to a Uint8Array.
    *
    * @param {WordArray} wordArray The word array.
    *
    * @return {Uint8Array} The Uint8Array.
    *
    * @static
    *
    * @example
    *
    * var u8arr = CryptoJS.enc.u8array.stringify(wordArray);
    */
    stringify: function (wordArray) {
    // Shortcuts
    var words = wordArray.words;
    var sigBytes = wordArray.sigBytes;
    // Convert
    var u8 = new Uint8Array(sigBytes);
    for (var i = 0; i < sigBytes; i++) {
    var byte = (words[i >>> 2] >>> (24 - (i % 4) * 8)) & 0xff;
    u8[i]=byte;
    }
    return u8;
    },
    /**
    * Converts a Uint8Array to a word array.
    *
    * @param {string} u8Str The Uint8Array.
    *
    * @return {WordArray} The word array.
    *
    * @static
    *
    * @example
    *
    * var wordArray = CryptoJS.enc.u8array.parse(u8arr);
    */
    parse: function (u8arr) {
    // Shortcut
    var len = u8arr.length;
    // Convert
    var words = [];
    for (var i = 0; i < len; i++) {
    words[i >>> 2] |= (u8arr[i] & 0xff) << (24 - (i % 4) * 8);
    }
    return CryptoJS.lib.WordArray.create(words, len);
    }
    };

    插件本身提供一个key、iv、明文均是WordArray的加密方法,而这个WordArray的数据格式长得非常像uint8数据,而
    这个组件的组件的功能就是是uint8数组和WordArray之间的互相转换。
    那么有了它我们就可以进行加解密了。

     
    // 服务端提供的32位key
    var akey = [0x26,0xAF,0xE2,0x1A,0x0C,0x16,0x73,0x54,0x13,0xFD,0x68,0xDD,0x8F,0xA0,0xB7,0xC1,0x57,0xA6,0x90,0xFF,0xCD,0xB3,0x54,0x61,0x10,0x07,0xD5,0x7E,0xDB,0x1E,0x4C,0xE9];
    // 服务端提供的16位iv
    var aiv = [0x15,0x4C,0xD3,0x55,0xFE,0xA1,0xFF,0x01,0x00,0x34,0xAB,0x22,0x08,0x4F,0x13,0x07];
     
    // 将key和iv转换成uint8数组
    var keyBv = new Uint8Array(akey);
    var ivBv = new Uint8Array(aiv);
     
    // 将key和iv转换成WordArray
    keyWA = CryptoJS.enc.u8array.parse(keyBv);
    ivWA = CryptoJS.enc.u8array.parse(ivBv);
     
    // 解密方法 传入密文的uint8数组
    function decryptU8arry(array) {
    var acontent = array;
    // 将密文转换成WordArray
    contentWA = CryptoJS.enc.u8array.parse(acontent);
    // 插件要求密文是base64格式
    var dcBase64String = contentWA.toString(CryptoJS.enc.Base64);
    // 解密 选定mode是CFB类型,无偏移量
    var decrypted = CryptoJS.AES.decrypt(dcBase64String, keyWA, { iv: ivWA,mode:CryptoJS.mode.CFB,padding:CryptoJS.pad.NoPadding});
    // 将解密后的明文转回uint8数组
    var bv = CryptoJS.enc.u8array.stringify(decrypted);
    return bv;
    }
     
    // 加密方法 传入明文的uint8数组
    function encryptU8arry(array) {
    var acontent = array;
    // 将明文转换成WordArray
    contentWA = CryptoJS.enc.u8array.parse(acontent);
    // 插件要求明文是base64格式
    var dcBase64String = contentWA.toString(CryptoJS.enc.Base64);
    // 加密 选定mode是CFB类型,无偏移量
    var encrypted = CryptoJS.AES.encrypt(contentWA, keyWA, { iv: ivWA,mode:CryptoJS.mode.CFB,padding:CryptoJS.pad.NoPadding});
    // 将密文转回uint8数组
    var bv = CryptoJS.enc.u8array.stringify(encrypted.ciphertext);
    return bv;
    }

    由此可以对二进制流进行加密解密了:

    var aData = [0,1,2,3,4];
    var dv = new Uint8Array(aData);
    var enu8 = encryptU8arry(dv); // 加密后的二进制流
    console.log(enu8);
    var deu8 = decryptU8arry(enu8); // 解密后的二进制流
    console.log(deu8);
  • 相关阅读:
    真的是最后一次作业了!!!!
    最后一次总结
    作业十一总结?
    作业十一总结
    实验十总结
    作业9总结
    附加作业
    补交第十次作业
    补交第九次作业
    补交第八次作业
  • 原文地址:https://www.cnblogs.com/chris-oil/p/8602968.html
Copyright © 2020-2023  润新知