【笔记】一些浏览器环境下的内置API

【笔记】一些浏览器环境下的内置API

panedioic
2021-07-06 / 0 评论 / 2 阅读 / 正在检测是否收录...

SHA-256

const hashBrowser = val =>
  crypto.subtle.digest('SHA-256', new TextEncoder('utf-8').encode(val)).then(h => {
    let hexes = [],
      view = new DataView(h);
    for (let i = 0; i < view.byteLength; i += 4)
      hexes.push(('00000000' + view.getUint32(i).toString(16)).slice(-8));
    return hexes.join('');
  });

hashBrowser(JSON.stringify({ a: 'a', b: [1, 2, 3, 4], foo: { c: 'bar' } })).then(console.log); // '04aa106279f5977f59f9067fa9712afc4aedc6f5862a8defc34552d8c7206393'

AES

function encrypt(data, keyJSON){

                var data = new TextEncoder("UTF-8").encode(data);

                var randomsKeys = geneRandomHexStr(64); // 128 bit keys

                var encryptedKey = hexStringToUint8Array(randomsKeys);

                var aesAlgo = {name: 'aes-cbc', iv: hexStringToUint8Array("000102030405060708090a0b0c0d0e0f")};

                return crypto.subtle.importKey("jwk", keyJSON, {name: "rsa-oaep", hash: {name: "sha-256"}},true, ['encrypt'])

                    .then(function(publicKey){

                        return crypto.subtle.encrypt({name: "rsa-oaep"}, publicKey, encryptedKey);

                    }).then(function(res){

                        encryptedKey = bytesToHexString(res)

                        // use aes to encrypt data

                        // import aes key

                        return crypto.subtle.importKey('raw', 

                            hexStringToUint8Array(randomsKeys) , aesAlgo, false, ['encrypt', 'decrypt']);

                         

                    }).then(function(result){

                        // use aes to encode

                        return crypto.subtle.encrypt(aesAlgo,

                         result, data);

                    }).then(function(encryptedData){

                        return Promise.resolve({

                            'encrypted': bytesToHexString(encryptedData),

                            'encryptedKey': encryptedKey,

                        });

                    });

 

                //console.log(new TextDecoder("UTF-8").decode(data));

                // use server public key to encrypt

                 

            }

 

            function decrypt(data, keyJSON){

                // use local private key to decrypt

                var encryptedKey = new hexStringToUint8Array(data.encryptedKey);

                var encryptedData = new hexStringToUint8Array(data.encrypted);

                var aesAlgo = {name: 'aes-cbc', iv: hexStringToUint8Array("000102030405060708090a0b0c0d0e0f")};

                // decrypt key

                return crypto.subtle.importKey('jwk', keyJSON, {name: "rsa-oaep", hash: {name: "sha-256"}}, true,

                    ['decrypt']).then(function(privateKey){

                        return crypto.subtle.decrypt({name: 'rsa-oaep'}, privateKey, encryptedKey);

                    }).then(function(decryptedKey){

                        // import aes key

                        return crypto.subtle.importKey('raw', 

                            decryptedKey, aesAlgo, false, ['encrypt', 'decrypt']);

                    }).catch(function(){

                        console.error("decrypt error");

                    }).then(function(result){

                        // decode encrypted data

                        return crypto.subtle.decrypt(aesAlgo, result, encryptedData);

                    }).then(function(data){

                        return Promise.resolve(new TextDecoder("UTF-8").decode(new Uint8Array(data)));

                    })

 

            }

 

            function createNewUserKey(){

                var algorithmKeyGen = {

                    name: "RSA-OAEP",

                    hash: {name: "sha-256"},

                    // RsaKeyGenParams

                    modulusLength: 2048,

                    publicExponent: new Uint8Array([0x01, 0x00, 0x01]),  // Equivalent to 65537

                };

                var nonExtractable = false;

                 

                var publicKey = "";

                var privateKey = "";

                var keyPairs = "";

                return crypto.subtle.generateKey(algorithmKeyGen, true, ['encrypt', 'decrypt']).then(function(result) {

                    // gene key pair

                    keyPairs = result;

                    return Promise.all([crypto.subtle.exportKey("jwk", keyPairs.publicKey),

                        crypto.subtle.exportKey("jwk", keyPairs.privateKey)]);

                })

                 

            }

 

            function _arrayBufferToBase64( buffer ) {

                var binary = '';

                var bytes = new Uint8Array( buffer );

                var len = bytes.byteLength;

                for (var i = 0; i < len; i++) {

                    binary += String.fromCharCode( bytes[ i ] );

                }

                return window.btoa( binary );

            }

 

            function hexStringToUint8Array(hexString) {

                if (hexString.length % 2 != 0)

                    throw "Invalid hexString";

                var arrayBuffer = new Uint8Array(hexString.length / 2);

                for (var i = 0; i < hexString.length; i += 2) {

                    var byteValue = parseInt(hexString.substr(i, 2), 16);

                    if (byteValue == NaN)

                        throw "Invalid hexString";

                    arrayBuffer[i/2] = byteValue;

                }

                return arrayBuffer;

            }

 

            function bytesToHexString(bytes) {

                if (!bytes)

                    return null;

                bytes = new Uint8Array(bytes);

                var hexBytes = [];

                for (var i = 0; i < bytes.length; ++i) {

                    var byteString = bytes[i].toString(16);

                    if (byteString.length < 2)

                        byteString = "0" + byteString;

                    hexBytes.push(byteString);

                }

                return hexBytes.join("");

            }

 

            function geneRandomHexStr(length){

                var text = "";

                var possible = "0123456789abcdef";

 

                for( var i=0; i < length; i++ )

                    text += possible.charAt(Math.floor(Math.random() * possible.length));

 

                return text;

            }

 

            createNewUserKey().then(function(keyPairs){

                encrypt("this is origin text", keyPairs[0]).then(function(res){

                    console.log('public', JSON.stringify(keyPairs[0]));

                    console.log('private', JSON.stringify(keyPairs[1]));

                    decrypt(res, keyPairs[1]).then(function(decrypted){

                        console.log('decrypted', decrypted);

                    });

                });

            })

SHA-256

代码

const hashBrowser = val =>
  crypto.subtle.digest('SHA-256', new TextEncoder('utf-8').encode(val)).then(h => {
    let hexes = [],
      view = new DataView(h);
    for (let i = 0; i < view.byteLength; i += 4)
      hexes.push(('00000000' + view.getUint32(i).toString(16)).slice(-8));
    return hexes.join('');
  });

示例

hashBrowser(JSON.stringify({ a: 'a', b: [1, 2, 3, 4], foo: { c: 'bar' } })).then(console.log); // '04aa106279f5977f59f9067fa9712afc4aedc6f5862a8defc34552d8c7206393'

Reference

浏览器 - 使用 SHA-256 创建一个 hash

References

浏览器 - 使用 SHA-256 创建一个 hash (advanced)
js 原生 aes rsa 加解密 及 CryptoJS 加解密
js-sha256的完整源码(来自谷歌)

0

评论 (0)

取消