简体   繁体   中英

SubtleCrypto ArrayBuffer Key to String

I've been looking at SublteCrypto to encrypt/decrypt text messages, and wanted to extract the key that is used to String, but using the same interface "SubtleCrypto" produces weird Strings for the key.

Now this is the code that I was playing with:

    Internal.crypto = {
    getRandomBytes: function(size) {
        var array = new Uint8Array(size);
        crypto.getRandomValues(array);
        return array.buffer;
    },
    encrypt: function(key, data, iv) {
        return crypto.subtle.importKey('raw', key, {name: 'AES-CBC'}, false, ['encrypt']).then(function(key) {
            return crypto.subtle.encrypt({name: 'AES-CBC', iv: new Uint8Array(iv)}, key, data);
        });
    },
    decrypt: function(key, data, iv) {
        return crypto.subtle.importKey('raw', key, {name: 'AES-CBC'}, false, ['decrypt']).then(function(key) {
            return crypto.subtle.decrypt({name: 'AES-CBC', iv: new Uint8Array(iv)}, key, data);
        });
    },
    sign: function(key, data) {
        return crypto.subtle.importKey('raw', key, {name: 'HMAC', hash: {name: 'SHA-256'}}, false, ['sign']).then(function(key) {
            return crypto.subtle.sign( {name: 'HMAC', hash: 'SHA-256'}, key, data);
        });
    },

    hash: function(data) {
        return crypto.subtle.digest({name: 'SHA-512'}, data);
    },

    HKDF: function(input, salt, info) {
        // Specific implementation of RFC 5869 that only returns the first 3 32-byte chunks
        // TODO: We dont always need the third chunk, we might skip it
        return Internal.crypto.sign(salt, input).then(function(PRK) {
            var infoBuffer = new ArrayBuffer(info.byteLength + 1 + 32);
            var infoArray = new Uint8Array(infoBuffer);
            infoArray.set(new Uint8Array(info), 32);
            infoArray[infoArray.length - 1] = 1;
            return Internal.crypto.sign(PRK, infoBuffer.slice(32)).then(function(T1) {
                infoArray.set(new Uint8Array(T1));
                infoArray[infoArray.length - 1] = 2;
                return Internal.crypto.sign(PRK, infoBuffer).then(function(T2) {
                    infoArray.set(new Uint8Array(T2));
                    infoArray[infoArray.length - 1] = 3;
                    return Internal.crypto.sign(PRK, infoBuffer).then(function(T3) {
                        return [ T1, T2, T3 ];
                    });
                });
            });
        });
    },

    // Curve 25519 crypto
    createKeyPair: function(privKey) {
        if (privKey === undefined) {
            privKey = Internal.crypto.getRandomBytes(32);
        }
        return Internal.Curve.async.createKeyPair(privKey);
    },
    ECDHE: function(pubKey, privKey) {
        return Internal.Curve.async.ECDHE(pubKey, privKey);
    },
    Ed25519Sign: function(privKey, message) {
        return Internal.Curve.async.Ed25519Sign(privKey, message);
    },
    Ed25519Verify: function(pubKey, msg, sig) {
        return Internal.Curve.async.Ed25519Verify(pubKey, msg, sig);
    }
};

What I've changed to get the key in String was:

    encrypt: function(key, data, iv) {
        var sKey = String.fromCharCode.apply(null, new Uint8Array(key));
        console.log('key ' + sKey);
        return crypto.subtle.importKey('raw', key, {name: 'AES-CBC'}, true, ['encrypt']).then(function(key) {
            return crypto.subtle.encrypt({name: 'AES-CBC', iv: new Uint8Array(iv)}, key, data);
        });
    },
    decrypt: function(key, data, iv) {
        var sKey = String.fromCharCode.apply(null, new Uint8Array(key));
        console.log('key ' + sKey);
        return crypto.subtle.importKey('raw', key, {name: 'AES-CBC'}, true, ['decrypt']).then(function(key) {
            return crypto.subtle.decrypt({name: 'AES-CBC', iv: new Uint8Array(iv)}, key, data);
        });
    }

I know that key in encrypt: function(key, data, iv) and decrypt: function(key, data, iv) is in ArrayBuffer, but I've tried everything to convert from ArrayBuffer to String, and it always produces incorrect encoded strings like Sask ç é

A cryptographic keys isn't text, or text encoded as bytes. It is a random byte sequence, so trying to decode it as a string is likely to irrevocably lose data.

Instead, use base-64 encoding ( btoa() ) and decoding ( atob() ) to convert binary data to strings and back again. The same applies to cipher text.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM