Mcrypt和base64与PHP和c# [英] Mcrypt and base64 with PHP and c#
问题描述
字符串:这是测试
密钥: 1234567812345678
PHP加密字符串: ybUaKwQlRNwOjJhxLWtLYQ ==
C#加密字符串: r2YjEFPyDDacnPmDFcGTLA ==
C#函数
static string Encrypt(string plainText,string key)
{
string cipherText;
var rijndael = new RijndaelManaged()
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128,
};
ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key,rijndael.IV);
使用(var memoryStream = new MemoryStream())
{
using(var cryptoStream = new CryptoStream(memoryStream,encryptor,CryptoStreamMode.Write))
{
使用(var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(plainText);
streamWriter.Flush();
}
cipherText = Convert.ToBase64String(memoryStream.ToArray());
//cryptoStream.FlushFinalBlock();
}
}
return cipherText;
}
private static string Decrypt(string cipherText,string key)
{
string plainText;
byte [] cipherArray = Convert.FromBase64String(cipherText);
var rijndael = new RijndaelManaged()
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128
};
ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key,rijndael.IV);
使用(var memoryStream = new MemoryStream(cipherArray))
{
using(var cryptoStream = new CryptoStream(memoryStream,decryptor,CryptoStreamMode.Read))
{
using(var streamReader = new StreamReader(cryptoStream))
{
plainText = streamReader.ReadToEnd();
}
}
}
返回plainText;
}
PHP功能
函数string_encrypt($ string,$ key){
$ crypted_text = mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
$ key,
$ string,
MCRYPT_MODE_ECB
);
return base64_encode($ crypted_text);
}
函数string_decrypt($ encrypted_string,$ key){
return mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
$ key,
base64_decode encrypted_string),
MCRYPT_MODE_ECB
);
}
我在C#中不是很好,我知道PHP功能正常工作。所以,在C#函数上必须做一些事情。可以将要加密的字符串转换为拉丁字符。
C#默认使用Rijndael填充,并使用PKCS7。
这意味着你必须按照PKCS7填写你的PHP端,下面的代码应该可以工作:
function string_encrypt($ string,$ key ){
$ block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128,MCRYPT_MODE_ECB);
$ padding = $ block - (strlen($ string)%$ block);
$ string。= str_repeat(chr($ padding),$ padding);
$ crypted_text = mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
$ key,
$ string,
MCRYPT_MODE_ECB
);
return base64_encode($ crypted_text);
}
有关更多信息,请参阅首先回答这里
我还应该添加,如果要更改C#方面而不使用填充,请进行以下修改而不是,并将PHP侧面放在一边:
static string Encrypt(string plainText,string key)
{
string cipherText;
var rijndael = new RijndaelManaged()
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128,
Padding = PaddingMode.Zeros,
};
ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key,null);
使用(var memoryStream = new MemoryStream())
{
using(var cryptoStream = new CryptoStream(memoryStream,encryptor,CryptoStreamMode.Write))
{
使用(var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(plainText);
streamWriter.Flush();
}
// cipherText = Convert.ToBase64String(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(memoryStream.ToArray())));
cipherText = Convert.ToBase64String(memoryStream.ToArray());
//cryptoStream.FlushFinalBlock();
}
}
return cipherText;
}
I have written the same methods in two platforms which I believe should result same thing but its not happening. I have encrypted the same text with same key which result different. Can someone figure it out why is it happening ?
String: this is test
Key: 1234567812345678
PHP encrypted string: ybUaKwQlRNwOjJhxLWtLYQ==
C# encrypted string: r2YjEFPyDDacnPmDFcGTLA==
C# functions
static string Encrypt(string plainText, string key)
{
string cipherText;
var rijndael = new RijndaelManaged()
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128,
};
ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, rijndael.IV);
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(plainText);
streamWriter.Flush();
}
cipherText = Convert.ToBase64String(memoryStream.ToArray());
//cryptoStream.FlushFinalBlock();
}
}
return cipherText;
}
private static string Decrypt(string cipherText, string key)
{
string plainText;
byte[] cipherArray = Convert.FromBase64String(cipherText);
var rijndael = new RijndaelManaged()
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128
};
ICryptoTransform decryptor = rijndael.CreateDecryptor(rijndael.Key, rijndael.IV);
using (var memoryStream = new MemoryStream(cipherArray))
{
using (var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read))
{
using (var streamReader = new StreamReader(cryptoStream))
{
plainText = streamReader.ReadToEnd();
}
}
}
return plainText;
}
PHP functions
function string_encrypt($string, $key) {
$crypted_text = mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
$key,
$string,
MCRYPT_MODE_ECB
);
return base64_encode($crypted_text);
}
function string_decrypt($encrypted_string, $key) {
return mcrypt_decrypt(
MCRYPT_RIJNDAEL_128,
$key,
base64_decode($encrypted_string),
MCRYPT_MODE_ECB
);
}
I am not so good in C# and I know the PHP function is working fine. So, there must be something done on C# functions. May be the string to be encrypted should converted to Latin chars.
C# does Rijndael padding by default and uses PKCS7.
This means you have to pad your PHP side as per PKCS7, code below should work:
function string_encrypt($string, $key) {
$block = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_ECB);
$padding = $block - (strlen($string) % $block);
$string .= str_repeat(chr($padding), $padding);
$crypted_text = mcrypt_encrypt(
MCRYPT_RIJNDAEL_128,
$key,
$string,
MCRYPT_MODE_ECB
);
return base64_encode($crypted_text);
}
For further information, see the first answer here
I should add also, that if you want to change the C# side and not use padding, make the below modification instead and leave the PHP side alone:
static string Encrypt(string plainText, string key)
{
string cipherText;
var rijndael = new RijndaelManaged()
{
Key = Encoding.UTF8.GetBytes(key),
Mode = CipherMode.ECB,
BlockSize = 128,
Padding = PaddingMode.Zeros,
};
ICryptoTransform encryptor = rijndael.CreateEncryptor(rijndael.Key, null);
using (var memoryStream = new MemoryStream())
{
using (var cryptoStream = new CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write))
{
using (var streamWriter = new StreamWriter(cryptoStream))
{
streamWriter.Write(plainText);
streamWriter.Flush();
}
//cipherText = Convert.ToBase64String(Encoding.UTF8.GetBytes(Encoding.UTF8.GetString(memoryStream.ToArray())));
cipherText = Convert.ToBase64String(memoryStream.ToArray());
//cryptoStream.FlushFinalBlock();
}
}
return cipherText;
}
这篇关于Mcrypt和base64与PHP和c#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!