如何用PHP解密PowerShell AES-192加密字符串?OpenSSL及替代方法咨询
PowerShell加密字符串的OpenSSL解密方案及优化
PowerShell加密逻辑说明
你提供的PowerShell代码通过ConvertFrom-SecureString -Key实现加密,底层采用AES-192-CBC算法,但输出的加密串是微软专属格式:
- 前缀固定为
76492d1116743f0423413b16050a5345(24个字符) - 后缀是Base64编码的二进制数据,包含16字节的IV(初始化向量)和实际密文
现有PHP代码的问题
- 密钥格式错误:PowerShell的整数数组不能直接在PHP中使用,需要转换为字节流字符串
- IV生成错误:IV已包含在加密串内,必须从加密串中提取,不能用随机生成的值
- 加密串未解析:直接传入完整加密串调用解密,未处理微软专属的前缀和内部结构
修正后的PHP解密代码
<?php $encrypted_string = "76492d1116743f0423413b16050a5345MgB8AHAAMwBnAE4AMwBsADcASQBLAEIANQBPAFAAKwBaAGgAUgBXAGwAaQBoAGcAPQA9AHwAZQA4ADUAOAA3ADEAOABhADMAOQBlADcAMABlADEAZAAzAGMAMgBjADEANQA3ADMANABjAGQAZgA4ADcAMwAyAGQANQBmAGIAMAA5ADUAYwA2ADcAOQBiADIAMAA3ADQANAA3ADYAMAAwAGIAYgA2AGQAZgAwAGYAMgBkADUANgA="; // 1. 解析加密字符串 $prefix = "76492d1116743f0423413b16050a5345"; $base64_part = substr($encrypted_string, strlen($prefix)); $binary_data = base64_decode($base64_part); // 提取IV(前16字节)和密文(剩余部分) $iv_size = 16; $iv = substr($binary_data, 0, $iv_size); $ciphertext = substr($binary_data, $iv_size); // 2. 转换密钥格式:将PowerShell整数数组转为字节字符串 $key_bytes = [21,123,21,3,141,13,14,253,151,13,11,241,36,21,18,17,61,11,21,9,5,21,17,28]; $key = implode(array_map('chr', $key_bytes)); // 3. 调用OpenSSL解密 $cipher = "aes-192-cbc"; $decrypted_data = openssl_decrypt($ciphertext, $cipher, $key, OPENSSL_RAW_DATA, $iv); echo $decrypted_data; // 输出:Test String ?>
更优的跨语言加密解密方案
如果需要跨语言(PowerShell + PHP/其他语言)实现加密解密,建议避开微软专属的ConvertFrom-SecureString格式,改用标准AES加密流程:
- 在PowerShell中手动实现AES加密,生成标准的IV+密文组合(比如将IV和密文分别Base64编码后用分隔符拼接,或分开存储)
- 其他语言直接按标准AES-CBC流程解析,无需处理微软专属格式
示例PowerShell标准加密代码:
$theKey = [byte[]](21,123,21,3,141,13,14,253,151,13,11,241,36,21,18,17,61,11,21,9,5,21,17,28) $theString = "Test String" $aes = New-Object System.Security.Cryptography.AesManaged $aes.KeySize = 192 $aes.Key = $theKey $aes.GenerateIV() $encryptor = $aes.CreateEncryptor() $plainBytes = [System.Text.Encoding]::UTF8.GetBytes($theString) $cipherBytes = $encryptor.TransformFinalBlock($plainBytes, 0, $plainBytes.Length) // 输出Base64编码的IV和密文,用|分隔 $ivBase64 = [Convert]::ToBase64String($aes.IV) $cipherBase64 = [Convert]::ToBase64String($cipherBytes) $output = "$ivBase64|$cipherBase64" Write-Output $output
这种方式生成的加密串兼容性更强,PHP只需拆分IV和密文即可直接解密,无需额外解析格式。
内容的提问来源于stack exchange,提问作者Mezzan
相关产品推荐
相关产品推荐

