SubtleCrypto ArrayBuffer Ключ к строке - PullRequest
0 голосов
/ 15 мая 2018

Я смотрел на SublteCrypto для шифрования / дешифрования текстовых сообщений и хотел извлечь ключ, который используется для String, но с использованием того же интерфейса «SubtleCrypto» создает странные строки для ключа.

Теперь это код, с которым я играл:

    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);
    }
};

То, что я изменил, чтобы получить ключ в String, было:

    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);
        });
    }

Я знаю, что key в encrypt: function(key, data, iv) и decrypt: function(key, data, iv) в ArrayBuffer, но я перепробовал все, чтобы преобразовать ArrayBuffer в String, и он всегда выдает некорректные закодированные строки, такие как Sask���ç é

1 Ответ

0 голосов
/ 15 мая 2018

Ключ шифрования не является текстом или текстом, закодированным в байтах. Это случайная последовательность байтов, поэтому попытка декодировать ее как строку может привести к безвозвратной потере данных.

Вместо этого используйте base-64 кодирование (btoa()) и декодирование (atob()) для преобразования двоичных данных в строки и обратно. То же самое относится и к зашифрованному тексту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...