VB.Net加密转PHP解密:求PHP字符串解密实现方案
刚接触PHP和密码学就搞跨语言解密确实有点挠头,不过别慌——核心思路就是把VB.Net里的解密步骤1:1对应到PHP里,关键是要抠准两边的加密参数细节。
首先得说个前提:你给出的VB.Net代码不全,比如DecryptString函数里的加密算法、密钥生成逻辑、IV和salt的处理方式这些核心信息都没写完,这些是跨语言解密的关键。我先基于.NET里最常见的加密场景(AES-CBC + Rfc2898DeriveBytes密钥推导)给你一套通用方案,你可以对照自己的VB.Net代码调整。
先拆解VB.Net常见的解密流程(假设你的代码是这类结构)
通常.NET里的字符串解密会是这样的逻辑(补全你没写完的部分):
Public Shared Function DecryptString(ByVal cipherTextStringWithSaltAndIv As String, ByVal password As String) As String
' 把Base64密文转成字节数组
Dim cipherBytes = Convert.FromBase64String(cipherTextStringWithSaltAndIv)
' 从字节数组里拆分salt、IV、实际密文(比如前8字节是salt,接下来16字节是IV)
Dim salt = cipherBytes.Take(8).ToArray()
Dim iv = cipherBytes.Skip(8).Take(16).ToArray()
Dim cipherText = cipherBytes.Skip(24).ToArray()
' 用密码和salt生成密钥(Rfc2898DeriveBytes本质是PBKDF2)
Dim deriveBytes As New Rfc2898DeriveBytes(password, salt, 1000)
Dim key = deriveBytes.GetBytes(32) ' 生成32字节密钥,对应AES-256
' AES-CBC模式解密,PKCS7填充
Using aes As New AesManaged()
aes.Key = key
aes.IV = iv
aes.Mode = CipherMode.CBC
aes.Padding = PaddingMode.PKCS7
Using decryptor = aes.CreateDecryptor()
Dim plainBytes = decryptor.TransformFinalBlock(cipherText, 0, cipherText.Length)
' .NET里常用Unicode(UTF-16LE)编码,转成字符串
Return Encoding.Unicode.GetString(plainBytes)
End Using
End Using
End Function
对应到PHP的实现代码
PHP里用OpenSSL扩展就能实现(mcrypt已经废弃,别用了),步骤和上面完全对应:
- 拆分密文中的salt、IV和实际密文
// 替换成你要解密的Base64字符串 $cipherTextWithSaltIv = "your_base64_cipher_text"; // 把Base64转成原始字节 $cipherBytes = base64_decode($cipherTextWithSaltIv); // 按照VB.Net里的规则拆分:前8字节是salt,接下来16字节是IV,剩下的是密文 $salt = substr($cipherBytes, 0, 8); $iv = substr($cipherBytes, 8, 16); $cipherText = substr($cipherBytes, 24);
- 生成和.NET一致的密钥
.NET的Rfc2898DeriveBytes用的是PBKDF2-SHA1,PHP用hash_pbkdf2就能实现,注意迭代次数、密钥长度必须和VB.Net里完全一样:
// 替换成解密密码 $password = "your_decryption_password"; $iterations = 1000; // 和VB.Net里的Rfc2898DeriveBytes第三个参数一致 $keyLength = 32; // 和VB.Net里GetBytes的参数一致(32是AES-256,16是AES-128) // 生成原始二进制密钥,最后一个true参数要加上,不然会返回十六进制字符串 $key = hash_pbkdf2("sha1", $password, $salt, $iterations, $keyLength, true);
- AES解密并转成正确编码的字符串
// 加密模式要和VB.Net对应:AES-256-CBC对应32字节密钥,AES-128-CBC对应16字节 $cipher = "aes-256-cbc"; // 解密:OPENSSL_RAW_DATA表示输入是原始字节,OpenSSL默认用PKCS7填充,和.NET一致 $plainTextRaw = openssl_decrypt($cipherText, $cipher, $key, OPENSSL_RAW_DATA, $iv); // .NET里用的是Encoding.Unicode(UTF-16LE),转成PHP常用的UTF-8 $plainText = mb_convert_encoding($plainTextRaw, "UTF-8", "UTF-16LE"); // 输出解密结果 echo $plainText;
关键注意事项(踩坑点!)
- 参数必须完全匹配:算法模式(CBC/ECB)、密钥长度、迭代次数、salt/IV的长度和拆分规则、字符串编码、填充方式,哪怕有一个不一样,解密出来的就是乱码或者直接失败。
- 如果你的VB.Net代码用的不是AES-CBC或者Rfc2898DeriveBytes,比如用了DES、ECB模式、或者自定义的密钥生成逻辑,一定要把完整的VB.Net代码贴出来,才能精准适配。
- 测试的时候可以先拿VB.Net加密一段已知的简单字符串(比如"test123"),再用PHP解密验证,这样能快速排查参数是否匹配。
内容的提问来源于stack exchange,提问作者nullfrog

