Python AES-CTR加密转PHP实现求助:结果不符且出现警告
Fixing Your AES-CTR PHP Implementation to Match Python Results
Let's break down the issues in your PHP code and fix them step by step to get the exact same encryption result as your Python script:
Key Problems in Your Current PHP Code
- Wrong Plaintext Handling: Your Python code uses a comma-separated string (
"E5ZA,K2JV,..."), but your PHP code converts each array element to a character withchr()—this creates completely invalid input for encryption. - Missing IV for CTR Mode: AES-CTR requires an initialization vector (which acts as the starting counter value). Your Python code uses
Counter.new(128)which defaults to a starting value of 0, but you didn't specify this in PHP, causing the warning and inconsistent results. - Default Base64 Output:
openssl_encryptreturns base64-encoded data by default. You were converting this base64 string to hex, which is not the same as converting raw encrypted bytes to hex like your Python code does.
Corrected PHP Code
<?php function strToHex($string){ $hex = ''; for ($i = 0; $i < strlen($string); $i++){ // Ensure single hex digits are padded to two characters (matches Python's hex format) $hex .= str_pad(dechex(ord($string[$i])), 2, '0', STR_PAD_LEFT); } return $hex; } // 1. Generate the same 256-bit key as Python $bytes = array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31); $lkey = implode(array_map("chr", $bytes)); $method = "AES-256-CTR"; // 2. Create the exact plaintext string used in Python $data = array("E5ZA", "K2JV", "PA01", "J1W3", "386S", "AGVZ", "9O9T", "F640", "FR20", "40LX", "D443", "1913", "031V"); $string = implode(',', $data); // Match the comma-separated format from Python // 3. Set CTR initial counter (IV) to 0 (matches Python's Counter.new(128) default) $iv = hex2bin('00000000000000000000000000000000'); // 4. Encrypt with raw binary output (no base64 encoding) $encrypted = openssl_encrypt($string, $method, $lkey, OPENSSL_RAW_DATA, $iv); // 5. Convert raw encrypted bytes to hex (same as Python's .hex()) echo strToHex($encrypted); ?>
Explanation of Changes
- Plaintext Fix: We use
implode(',', $data)to replicate the exact comma-separated string your Python code uses, instead of the incorrect character conversion. - IV Addition: The
$ivvariable is a 16-byte (128-bit) string of zeros, which matches the default starting counter value ofCounter.new(128)in Python. This eliminates the warning and ensures the counter starts at the same point. - Raw Output Option: Adding
OPENSSL_RAW_DATAmakesopenssl_encryptreturn raw encrypted bytes instead of base64-encoded data, so converting to hex gives the same result as your Python code'sencryptedtext.hex(). - strToHex Improvement: We added padding to ensure single-hex characters (like 0x0a) are formatted as two digits, matching Python's consistent hex output.
Running this corrected code will produce your expected result: b5682cef66f2adaff0dacb7078f31a773feb86f28614b5ee24e9ee634200a8d6eb177a151eb55003c6cc81b3e9cb6d1a1673a2881ec194370af242d9f1fd5818
内容的提问来源于stack exchange,提问作者user3224813
相关产品推荐
相关产品推荐

