簡體   English   中英

Openssl aes-256-cbc 從命令提示符加密,在 PHP 中解密(反之亦然)

[英]Openssl aes-256-cbc encryption from command prompt and decryption in PHP (and vice versa)

我正在嘗試通過 Windows 命令提示符加密 (openssl aes-256-cbc) 一個字符串,並在 PHP 中解密結果。

我通過以下方式完成了加密:

echo {un:est@test.com,upass:klkKJS*dfd!j@d76w} | openssl enc -e -aes-256-cbc -a -salt -pass pass:sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KT

解密的話,我的php密碼是:

$ivlen = openssl_cipher_iv_length('aes-256-cbc');
$iv = openssl_random_pseudo_bytes($ivlen);
echo openssl_decrypt('U2FsdGVkX18ruQUgA9LEOOvdOUQXv/o8z6ZNO820MKzSIbMjFcyfNo1efQwAOINxMY9+UxZjxaT+JEWmlUyYQw==', 'aes-256-cbc', 'sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KT', $options=0, $iv);

但是解密后的字符串是空的。 請幫忙。

(注意:我還需要做相反的過程,即在 php 中加密,然后在 WIN 命令提示符下解密。所以請添加任何可能有幫助的建議。)

OpenSSL 語句在加密期間生成一個隨機的 8 字節鹽,它與密碼一起使用以派生一個 32 字節密鑰和一個 16 字節 IV 與 OpenSSL function EVP_BytesToKey()

使用密鑰和 IV,在 CBC 模式下使用 AES-256 執行加密。 結果由Salted__的 ASCII 編碼串聯組成,后跟鹽和實際密文,所有 Base64 編碼。

PHP/OpenSSL 中的解密必須按如下方式實現:

  • 確定鹽和實際密文。
  • 使用鹽、密碼和EVP_BytesToKey()獲取密鑰和 IV。
  • 使用密鑰和 IV 在 CBC 模式下使用 AES-256 執行解密。

一種可能的實現是:

<?php
function EVP_BytesToKey($salt, $password) {
    $bytes = '';
    $last = '';
    while(strlen($bytes) < 48) {
        $last = hash('md5', $last . $password . $salt, true);
        $bytes.= $last;
    }
    return $bytes;
} 
    
$saltCiphertext = base64_decode('U2FsdGVkX18ruQUgA9LEOOvdOUQXv/o8z6ZNO820MKzSIbMjFcyfNo1efQwAOINxMY9+UxZjxaT+JEWmlUyYQw==');
$salt = substr($saltCiphertext, 8, 8);
$ciphertext = substr($saltCiphertext, 16);
$keyIv = EVP_BytesToKey($salt, 'sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KT');
$key = substr($keyIv, 0, 32);
$iv = substr($keyIv, 32);
echo openssl_decrypt($ciphertext, 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv); // {un:est@test.com,upass:klkKJS*dfd!j@d76w}
?>

在早期版本中,OpenSSL 默認使用 MD5 作為EVP_BytesToKey()中的摘要,從版本 V1.1.0 SHA256 開始。 在貼出的例子中,用MD5解密是成功的,所以顯然加密時使用了MD5。
請注意,如今使用EVP_BytesToKey()進行密鑰派生被認為是不安全的。

正如@Topaco針對 PHP openssl 解密通過命令提示符編碼的字符串所建議的那樣,這里是一個相反的示例(PHP 加密以在命令行中解碼)。 感謝@Topaco 的評論和這段代碼

<?php
function EVP_BytesToKey($salt, $password) {
    $bytes = '';
    $last = '';
    while(strlen($bytes) < 48) {
        $last = hash('md5', $last . $password . $salt, true);
        $bytes.= $last;
    }
    return $bytes;
}

$saltDeciphertext= '{un:est@test.com,upass:klkKJS*dfd!j@d76w}';
$crypttext = "Salted__";
$salt= random_bytes(8);
$crypttext .= $salt;
$keyIV= EVP_BytesToKey($salt, 'sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KT');
$key = substr($keyIV, 0, 32);
$iv = substr($keyIV, 32);
$crypttext .= openssl_encrypt($saltDeciphertext, 'AES-256-CBC', $key, OPENSSL_RAW_DATA, $iv);
echo base64_encode($crypttext);
?>

后續解密命令:

echo U2FsdGVkX1+rDCycmwvc6rImKmrzaC9WTlzFanXt476975aYQcxPt2fgnRazm7CorGkpAWm9vmcu33YpiTYziw== | openssl enc -d -aes-256-cbc -a -salt -pass pass:sw8/M!CLl:=cmgtHts?v/Wb7C$Vk9Sy-{go.*+E;[GAg~KQi*rI!1#z;x/KT

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM