php与csharp通讯,我如何才能使CSharp / .NET与PHP加密的字符串...

博主在尝试使用C#和PHP进行Rijndael128位CBC模式加密时遇到了不一致的结果。尽管加密后的字符串长度相同,但内容不同,导致PHP可以解密自身和C#加密的字符串,而C#只能解密自己加密的字符串。这引发了关于跨平台加密解密兼容性的讨论。
摘要由CSDN通过智能技术生成

(前言:我是一个具有加密和安全性的新手,认为这是一种有趣的学习方式)

我正在用C#构建一个程序,该程序与使用标准HTTP协议用PHP编写的服务器通信.我希望两个程序都能够发送和接收加密的数据.但是,尽管加密和加密都使用相同的功能,但在处理方式上似乎存在不一致之处.

这两个程序在CBC模式下都使用Rjindael 128位.

为了演示/测试,我制作了两个几乎相同的函数,每个函数采用相同的字符串,对其进行加密,然后将结果作为base64字符串吐出.

PHP函数:

public static function EncryptionTest () {

echo 'Testing Encryption to base64 string...
';

$originalString = 'This is the original String! How cool is that?';

$key = "abcdefghijklmnopqrstuvwxyz012345";

$iv = "1234567890123456";

$encrypted = mcrypt_encrypt (MCRYPT_RIJNDAEL_128, $key, $originalString, MCRYPT_MODE_CBC, $iv);

echo base64_encode ($encrypted);

}

与C#对应:

public static void EncryptionTest ()

{

System.Console.WriteLine ("Testing Encryption to base64 string...");

string originalString = "This is the original String! How cool is that?";

byte [] encryptedData;

byte [] key = System.Text.ASCIIEncoding.UTF8.GetBytes ("abcdefghijklmnopqrstuvwxyz012345");

byte [] iv = System.Text.ASCIIEncoding.UTF8.GetBytes ("1234567890123456");

RijndaelManaged cryptor = new RijndaelManaged ();

cryptor.Key = key;

cryptor.IV = iv;

cryptor.BlockSize = 128;

cryptor.Mode = CipherMode.CBC;

ICryptoTransform encryptor = cryptor.CreateEncryptor (cryptor.Key, cryptor.IV);

using (MemoryStream msEncrypt = new MemoryStream ())

{

using (CryptoStream csEncrypt = new CryptoStream (msEncrypt, encryptor, CryptoStreamMode.Write))

{

using (StreamWriter swEncrypt = new StreamWriter (csEncrypt) )

{

swEncrypt.Write (originalString);

}

encryptedData = msEncrypt.ToArray ();

}

}

System.Console.WriteLine (System.Convert.ToBase64String (encryptedData) );

}

现在,这是PHP结果:

Testing Encryption to base64 string…

yzwIdowhLj+cMOFPMuHSA80pWQ6R8yfFQlEsLx5kIzUOJdFykLjsaKfK4VfaBGRv

和C#结果:

Testing Encryption to base64 string…

yzwIdowhLj+cMOFPMuHSA80pWQ6R8yfFQlEsLx5kIzUg74mGEQf9iW+OQ68m6cpp

如您所见,这两个结果都经过明确加密(好),字符数相同(好),但不同(可能不好).

我编写了解密测试,接受这些字符串并对其进行处理.这是PHP函数:

public static function DecryptionTest () {

$phpBase64 = 'yzwIdowhLj+cMOFPMuHSA80pWQ6R8yfFQlEsLx5kIzUOJdFykLjsaKfK4VfaBGRv';

$csBase64 = 'yzwIdowhLj+cMOFPMuHSA80pWQ6R8yfFQlEsLx5kIzUg74mGEQf9iW+OQ68m6cpp';

$key = "abcdefghijklmnopqrstuvwxyz012345";

$iv = "1234567890123456";

$phpEncrypted = base64_decode ($phpBase64);

$phpDecrypted = mcrypt_decrypt (MCRYPT_RIJNDAEL_128, $key, $phpEncrypted, MCRYPT_MODE_CBC, $iv);

$csEncrypted = base64_decode ($csBase64);

$csDecrypted = mcrypt_decrypt (MCRYPT_RIJNDAEL_128, $key, $csEncrypted, MCRYPT_MODE_CBC, $iv);

echo 'Decrypted PHP string: "' . $phpDecrypted . '"
' .

'Decrypted CS string: "' . $csDecrypted . '"';

}

和C#版本:

public static void DecryptionTest ()

{

System.Console.WriteLine ("Testing Decryption for PHP and CS generated base64 strings!");

string phpBase64 = "yzwIdowhLj+cMOFPMuHSA80pWQ6R8yfFQlEsLx5kIzUOJdFykLjsaKfK4VfaBGRv";

string csBase64 = "yzwIdowhLj+cMOFPMuHSA80pWQ6R8yfFQlEsLx5kIzUg74mGEQf9iW+OQ68m6cpp";

byte [] phpEncrypted = System.Convert.FromBase64String (phpBase64);

byte [] csEncrypted = System.Convert.FromBase64String (csBase64);

string phpDecrypted;

string csDecrypted;

byte [] encryptedData;

byte [] key = System.Text.ASCIIEncoding.UTF8.GetBytes ("abcdefghijklmnopqrstuvwxyz012345");

byte [] iv = System.Text.ASCIIEncoding.UTF8.GetBytes ("1234567890123456");

RijndaelManaged cryptor = new RijndaelManaged ();

cryptor.Key = key;

cryptor.IV = iv;

cryptor.BlockSize = 128;

cryptor.Mode = CipherMode.CBC;

ICryptoTransform decryptor = cryptor.CreateDecryptor (cryptor.Key, cryptor.IV);

using (MemoryStream msDecrypt = new MemoryStream (csEncrypted))

{

using (CryptoStream csDecrypt = new CryptoStream (msDecrypt, decryptor, CryptoStreamMode.Read))

{

using (StreamReader swDecrypt = new StreamReader (csDecrypt) )

{

csDecrypted = swDecrypt.ReadToEnd ();

}

}

}

System.Console.WriteLine ("Decrypted CS string: \"" + csDecrypted + "\"");

using (MemoryStream msDecrypt = new MemoryStream (phpEncrypted))

{

using (CryptoStream csDecrypt = new CryptoStream (msDecrypt, decryptor, CryptoStreamMode.Read))

{

using (StreamReader swDecrypt = new StreamReader (csDecrypt) )

{

phpDecrypted = swDecrypt.ReadToEnd ();

}

}

}

System.Console.WriteLine ("Decrypted PHP string: \"" + phpDecrypted + "\"");

}

PHP结果:

Decrypted PHP string: “This is the original String! How cool is that?”

Decrypted CS string: “This is the original String! How cool is that?”

和C#结果:

Decrypted CS string: “This is the original String! How cool is that?”

CryptographicException: Bad PKCS7 padding. Invalid length 0.

at Mono.Security.Cryptography.SymmetricTransform.ThrowBadPaddingException (PaddingMode padding, Int32 length, Int32 position) [0x0005c] in > /Applications/buildAgent/work/84669f285f6a667f/mcs/class/corlib/Mono.Security.Cryptography/SymmetricTransform.cs:363

因此,基本上,PHP代码可以成功解密两个base64字符串,但是C#代码只能解密由其自己的解密程序创建的base64字符串.

其中很多是我在互联网上找到的代码,可以根据自己的需要进行修改.就像我说的那样,我是密码学的新手,但是我在这里已经很不错了.我可以整天进行理论化和测试,但是它开始陷入我的日程安排中,因此我正在寻找其他人对其不起作用的见解.谢谢!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值