我有麻煩解密在PHP與openssl_encrypt
方法加密的消息。我正在使用新的WebCrypto API(所以我使用crypto.subtle
)。麻煩解密OpenSSL的AES CTR加密文本
加密在PHP中:
$ALGO = "aes-256-ctr";
$key = "ae6865183f6f50deb68c3e8eafbede0b33f9e02961770ea5064f209f3bf156b4";
function encrypt ($data, $key) {
global $ALGO;
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length($ALGO), $strong);
if (!$strong) {
exit("can't generate strong IV");
}
return bin2hex($iv).openssl_encrypt($data, $ALGO, $key, 0, $iv);
}
$enc = encrypt("Lorem ipsum dolor", $key);
exit($enc);
輸出示例:
8d8c3a57d2dbb3287aca61be0bce59fbeAQ4ILKouAQ5eizPtlUTeHU=
(我可以解密,在PHP,並得到明文背面)
在JS我解密這樣的:
function Ui8FromStr (StrStart) {
const Ui8Result = new Uint8Array(StrStart.length);
for (let i = 0; i < StrStart.length; i++) {
Ui8Result[i] = StrStart.charCodeAt(i);
}
return Ui8Result;
}
function StrFromUi8 (Ui8Start) {
let StrResult = "";
Ui8Start.forEach((charcode) => {
StrResult += String.fromCharCode(charcode);
});
return StrResult;
}
function Ui8FromHex (hex) {
for (var bytes = new Uint8Array(Math.ceil(hex.length/2)), c = 0; c < hex.length; c += 2)
bytes[c/2] = parseInt(hex.substr(c, 2), 16);
return bytes;
}
const ALGO = 'AES-CTR'
function decrypt (CompCipher, HexKey) {
return new Promise (function (resolve, reject) {
// remove IV from cipher
let HexIv = CompCipher.substr(0, 32);
let B64cipher = CompCipher.substr(32);
let Ui8Cipher = Ui8FromStr(atob(B64cipher));
let Ui8Iv = Ui8FromHex (HexIv);
let Ui8Key = Ui8FromHex (HexKey);
crypto.subtle.importKey("raw", Ui8Key, {name: ALGO}, false, ["encrypt", "decrypt"]). then (function (cryptokey){
return crypto.subtle.decrypt({ name: ALGO, counter: Ui8Iv, length: 128}, cryptokey, Ui8Cipher).then(function(result){
let Ui8Result = new Uint8Array(result);
let StrResult = StrFromUi8(Ui8Result);
resolve(StrResult);
}).catch (function (err){
reject(err)
});
})
})
}
當我現在運行decrypt("8d8c3a57d2dbb3287aca61be0bce59fbeAQ4ILKouAQ5eizPtlUTeHU=", "ae6865183f6f50deb68c3e8eafbede0b33f9e02961770ea5064f209f3bf156b4").then(console.log)
我得到亂碼:SÌõÅ°blfçSÑ-
我的問題是,我不知道什麼是counter
。我嘗試了IV,但失敗了。
This Github tutorial提示* ,它是IV - 或至少它的一部分,因爲我已經看到人們談論計數器是IV的一部分(類似4個字節,這意味着,四是從12個字節IV和4字節計數器)
如果這確實是真的做,那麼我的問題是:我在哪裏給腳本的其他12個字節IV的櫃檯時,只有4字節它。
誰能也許給我的加密工作的例子在PHP
* 它說,同樣的櫃檯已被用於烯和解密。這使我相信,這是至少類似於IV
@zaph輸出被做出來的十六進制IV的32個字符(16個字節)+爲Base64密文的24個字符(17個字節) 密文總= 16 + 17 = 33 –
@zaph什麼導致你認爲密文是24字節?正如我所說,它已經預先IV,但IV是在十六進制。因此,基數64中的密文僅爲17個字節(16字節的十六進制前綴 - 即32個字符的十六進制前綴) –
您擁有的是對IV和Base64編碼的加密數據進行十六進制編碼的錯誤混合。這是一個非常糟糕的主意,它肯定會使我困惑,並且肯定會失敗[「最少驚奇規則」](http://principles-wiki.net/principles:Principle%20of%20Least%20Surprise?redirect=1),In界面設計,總是做最不令人意外的事情。 – zaph