-3 php c# encryption aes encryption-symmetric
我正在与客户进行数据交换集成,他们发送给我的数据使用他们的C#encrypt方法加密(如下).
我的应用程序运行PHP 5.3,我需要一个等效的代码来解密他们发送的数据.我有PHP代码,但它不能正确解密客户端数据.
很明显,我在加密/解密方法,IV键或其他方面犯了一些错误.谁能发现错误?
谢谢.
C#代码(来自我的客户):
using System;
using System.Security.Cryptography;
using System.Text;
using System.IO;
public class Program
{
public static void Main()
{
var text = "this is a plain string";
var enc = Program.Encrypt(text);
Console.WriteLine(enc);
Console.WriteLine(Program.Decrypt(enc));
}
public static string Encrypt(string clearText)
{
var EncryptionKey = "1234567890123456";
byte[] clearBytes = Encoding.Unicode.GetBytes(clearText);
using (Aes encryptor = Aes.Create())
{
byte[] IV = new byte[15];
var rand = new Random();
rand.NextBytes(IV);
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateEncryptor(), CryptoStreamMode.Write))
{
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
}
clearText = Convert.ToBase64String(IV) + Convert.ToBase64String(ms.ToArray());
}
}
return clearText;
}
public static string Decrypt(string cipherText)
{
var EncryptionKey = "1234567890123456";
byte[] IV = Convert.FromBase64String(cipherText.Substring(0, 20));
cipherText = cipherText.Substring(20).Replace(" ", "+");
byte[] cipherBytes = Convert.FromBase64String(cipherText);
using (Aes encryptor = Aes.Create())
{
Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, IV);
encryptor.Key = pdb.GetBytes(32);
encryptor.IV = pdb.GetBytes(16);
using (MemoryStream ms = new MemoryStream())
{
using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
{
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
}
cipherText = Encoding.Unicode.GetString(ms.ToArray());
}
}
return cipherText;
}
}
Run Code Online (Sandbox Code Playgroud)
PHP代码我有:
public function encrypt($plainText)
{
$secretKey = '1234567890123456';
return rtrim(
base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256,
$secretKey, $plainText,
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB
),
MCRYPT_RAND)
)
), "\0"
);
}
public function decrypt($encodedData)
{
$secretKey = '1234567890123456';
return rtrim(
mcrypt_decrypt(
MCRYPT_RIJNDAEL_256,
$secretKey,
base64_decode($encodedData),
MCRYPT_MODE_ECB,
mcrypt_create_iv(
mcrypt_get_iv_size(
MCRYPT_RIJNDAEL_256,
MCRYPT_MODE_ECB
),
MCRYPT_RAND
)
), "\0"
);
}
Run Code Online (Sandbox Code Playgroud)
Sco*_*ski 10
谁能发现错误?
是的,而最重要的不是你的错:mcrypt令人困惑的API再次罢工.
也就是说,这里实际上存在多个错误.
return rtrim( // unnecessary
base64_encode(
mcrypt_encrypt(
MCRYPT_RIJNDAEL_256, // Not AES
$secretKey, $plainText,
MCRYPT_MODE_ECB, // BAD, use MCRYPT_MODE_CBC or 'ctr' instead
mcrypt_create_iv(
mcrypt_get_iv_size( // unless you're going make this
MCRYPT_RIJNDAEL_256, // configurable, you should just
MCRYPT_MODE_ECB // hard-code this as an integer
),
MCRYPT_RAND) // BAD, use MCRYPT_DEV_URANDOM
)
), "\0"
);
Run Code Online (Sandbox Code Playgroud)
如果您要生成IV,则应进行通信,以便您的收件人可以成功解密相同的第一个块.C#代码执行此操作,而PHP则不这样做.
从加密工程的角度来看,您应该考虑在C#land和PHP中部署Encrypt然后Authenticate协议.请参阅有关加密和身份验证的博文.此外,您编写的所有加密代码可能都已损坏.
| 归档时间: |
|
| 查看次数: |
1573 次 |
| 最近记录: |