我要做的是使用 Web 浏览器中 SubtleCrypto.encrypt() 提供的 128 位 AES-CBC 加密来加密 16 字节的数据包。
我期望找到的是 16 字节的加密数据用于 16 字节的输入。
我实际发现的是 16 字节输入的 32 字节加密数据。
具体来说,15 字节的输入产生 16 字节的输出,16 字节的输入产生 32 字节的输出,17 字节的数据产生 32 字节的输出。
我的问题是,为什么 16 字节的输入数据会产生 32 字节的输出?我会怀疑这可能只发生在 > 16 字节的输入数据,而不是 >= 16 字节的情况下。
将以下测试代码保存到文件并使用 Web 浏览器打开。
<html>
<head>
<script>
var myKey = window.crypto.getRandomValues(new Uint8Array(16));
console.log("Raw key = " + myKey);
var keyObj = {};
var keyFormat = "raw";
var extractable = false;
var usages = ["encrypt", "decrypt"];
window.crypto.subtle.importKey(keyFormat, myKey, "AES-CBC", extractable, usages)
.then(function(importedKey) {
keyObj = importedKey;
console.log("Encryption/Decryption key object = " + keyObj);
var vector = window.crypto.getRandomValues(new Uint8Array(16));
var encryptThis15 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
var encryptThis16 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]);
var encryptThis17 = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17]);
var decryptSuccess = function(decrypted) {
var decryptedData = new Uint8Array(decrypted);
console.log("Decrypted data = " + decryptedData.length + " bytes: " + decryptedData);
};
var decryptFail = function(error) {
// Fail.
console.log("Failure decrypting data. Error: " + error);
};
var encryptSuccess = function(encData) {
var encryptedData = new Uint8Array(encData);
console.log("Encrypted data = " + encryptedData.length + " bytes: " + encryptedData);
return encData;
};
var encryptFail = function(error) {
console.log("Failure encrypting data. Error: " + error);
};
console.log("15 byte data array as input = " + encryptThis15);
window.crypto.subtle.encrypt({name: "AES-CBC", iv: vector}, keyObj, encryptThis15)
.then(encryptSuccess)
.then(function(encrypted){return window.crypto.subtle.decrypt({name: "AES-CBC", iv: vector}, keyObj, encrypted);})
.then(decryptSuccess)
.catch(decryptFail);
console.log("16 byte data array as input = " + encryptThis16);
window.crypto.subtle.encrypt({name: "AES-CBC", iv: vector}, keyObj, encryptThis16)
.then(encryptSuccess)
.then(function(encrypted){return window.crypto.subtle.decrypt({name: "AES-CBC", iv: vector}, keyObj, encrypted);})
.then(decryptSuccess)
.catch(decryptFail);
console.log("17 byte data array as input = " + encryptThis17);
window.crypto.subtle.encrypt({name: "AES-CBC", iv: vector}, keyObj, encryptThis17)
.then(encryptSuccess)
.then(function(encrypted){return window.crypto.subtle.decrypt({name: "AES-CBC", iv: vector}, keyObj, encrypted);})
.then(decryptSuccess)
.catch(decryptFail);
})
.catch(function(err){
console.log("Key generation error = " + err);
});
</script>
<title>WebCrypto encrypt test</title>
</head>
<body>
<p>See console log.</p>
</body>
</html>