【发布时间】:2017-09-22 10:12:24
【问题描述】:
我正在尝试将此 C# 代码移植到 PHP:
private static string DecryptString(string content, string password)
{
Rijndael aes;
byte[] retVal = null;
byte[] contentBytes;
byte[] passwordBytes;
byte[] ivBytes;
try {
//Get the content as byte[]
contentBytes = Convert.FromBase64String(content);
//Create the password and initial vector bytes
passwordBytes = new byte[32];
ivBytes = new byte[16];
Array.Copy(Encoding.Unicode.GetBytes(password), passwordBytes, Encoding.Unicode.GetBytes(password).Length);
Array.Copy(passwordBytes, ivBytes, 16);
//Create the cryptograpy object
aes = Rijndael.Create();
aes.Key = passwordBytes;
aes.IV = ivBytes;
aes.Padding = PaddingMode.PKCS7;
string mode = aes.Mode.ToString();
//Decrypt
retVal = aes.CreateDecryptor().TransformFinalBlock(contentBytes, 0, contentBytes.Length);
}
catch {}
return Encoding.Unicode.GetString(retVal);
}
content 参数是一个 44 个字符长的字符串,base 64 编码,password 参数是一个 6 个字符长的字符串。
这是我整理的 PHP 代码:
$content = "[44 char base 64 encoded string]";
$password = "[6 char password]";
$padding = 32 - (strlen($password) % 32);
$password .= str_repeat(chr($padding), $padding);
$iv = substr($password, 0, 16);
$data = base64_decode($content);
$decrypted = openssl_decrypt($data, 'AES-256-CBC', $password, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv);
C# 代码的结果是一个 10 字符长的数字。 PHP 的结果是一些 32 个字符长的乱码——我猜是二进制数据。
谁能帮我修复该代码,或者知道我可以尝试什么?
【问题讨论】:
-
基本上代码是不安全的。应使用具有密钥派生功能(例如 PBKDF2)的密码创建密钥。每次加密的 IV 应该是随机的,而不是密码/密钥。 IV 可以并且通常预先添加到加密数据中,它们不需要保密。
-
@zaph 我知道 - 但我无法更改 C# 代码,只需将其移植到 PHP :-)
-
啊,所以你不关心安全,我错误地认为安全是目标。
-
@zaph 我是。但在这种情况下,我无能为力。这是我正在使用的服务 - 由其他人创建。
-
你选择消费它。您选择帮助使事情更安全还是更不安全,这就是问题所在。我们确实需要朝着更安全的方向发展。事后每个人都有借口,他们都归结为“不够在意”。看来你选择了“不在乎”。
标签: c# php encryption aes