一个合作伙伴正在使用c#将12位数字加密到数据库中,我需要在Unix服务器上理想地使用php 5.6解码这些值,但是php 7.2,perl 5.16或python 3.6都可用。
我从php openssl-encrypt手册的示例2开始,这使我得到了一些可以成功编码/解码测试字符串但不能解码c#编码数据的东西。
我也曾在https://odan.github.io/2017/08/10/aes-256-encryption-and-decryption-in-php-and-csharp.html尝试过这些建议,但均未成功,大概是因为合作伙伴未使用CBC。
用$key = substr(hash('sha256', $secret, true), 0, 32);
代替函数调用中的秘密没有帮助。
我尝试了openssl-encrypt支持的所有密码,但均未成功。
合作伙伴提供了他们的c#代码(与Microsoft示例代码差不多,它直接起了作用):
public static string EncryptString(string key, string plainText)
{
byte[] iv = new byte[16];
byte[] array;
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream())
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
{
using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
{
streamWriter.Write(plainText);
}
array = memoryStream.ToArray();
}
}
}
return Convert.ToBase64String(array);
}
public static string DecryptString(string key, string cipherText)
{
byte[] iv = new byte[16];
byte[] buffer = Convert.FromBase64String(cipherText);
using (Aes aes = Aes.Create())
{
aes.Key = Encoding.UTF8.GetBytes(key);
aes.IV = iv;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (MemoryStream memoryStream = new MemoryStream(buffer))
{
using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
{
using (StreamReader streamReader = new StreamReader((Stream)cryptoStream))
{
return streamReader.ReadToEnd();
}
}
}
}
}
我目前具有以下功能:
function encrypt2($data, $secret, $cipher, $iv)
{
$ivlen = openssl_cipher_iv_length($cipher);
$ciphertext_raw = openssl_encrypt($data, $cipher, $secret, $options=OPENSSL_RAW_DATA, $iv);
$hmac = hash_hmac('sha256', $ciphertext_raw, $secret, $as_binary=true);
return base64_encode($ciphertext_raw);
}
function decrypt2($data, $secret, $cipher, $iv)
{
$c = base64_decode($data);
$ivlen = openssl_cipher_iv_length($cipher);
$original_plaintext = openssl_decrypt($c, $cipher, $secret, $options=OPENSSL_RAW_DATA, $iv);
return ($original_plaintext ? $original_plaintext : 'openssl_decrypt failed');
}
我无法共享合作伙伴数据,因为我只有真实数据,但是下面是对php函数的示例调用,其中第二个函数产生的结果类似于真实数据:
$data = '123456789012';
$secret = "qwertyuiop12345";
$cipher = "AES-256-ECB";
$iv = "";
$encrypted2 = encrypt2($data, $secret, $cipher, $iv);
$decrypted2 = decrypt2($encrypted2, $secret, $cipher, $iv);
echo "$data > $encrypted2 > $decrypted2\n";
礼物:
123456789012 > NDdefqxcYZvtjAcvPrQ00A== > 123456789012
我需要对我的php进行哪些更改以匹配C#代码?
或者使用perl或python的解决方案也可以。
使用示例数据更新:
xyz@gmail.com
用b14ca5898a4e4133bbce2ea2315a1916
加密后得到c4Eej4S8G3mclVQJb+qkfQ==
这正是我的代码生成的。
我获得的活动密钥长16个字符,但是上面的示例使用了32个字符串,是否已在使用前进行了将原始密钥的长度加倍的操作?