gpt4 book ai didi

C#加密到PHP解密

转载 作者:IT王子 更新时间:2023-10-29 00:07:46 27 4
gpt4 key购买 nike

我试图在 C# 中加密一些(cookie)数据,然后在 PHP 中解密。我选择使用 Rijndael 加密。我几乎已经开始工作了,只是只有部分文本被解密了!我从这个例子开始工作:Decrypt PHP encrypted string in C#

这是我正在加密的文本 (JSON)(已删除敏感信息):

{"DisplayName":"xxx", "Username": "yyy", "EmailAddress":"zzz"}

所以我登录到 C# 应用程序,它根据存储的 key 和 IV 创建/编码 cookie,然后重定向到应该解密/读取 cookie 的 PHP 应用程序。当我解密 cookie 时,它​​是这样的:<罢工>

<罢工>
{"DisplayName":"xxx","F�A ;��HP=D�������4��z����ť���k�#E���R�j�5�\�t. t�D��" 

更新:我已经更进一步了,这就是现在的结果

string(96) "{"DisplayName":"xxx","Username":"yyy","EmailAddress"�)ق��-�J��k/VV-v� �9�B`7^" 

如您所见,它开始解密,但随后变得一团糟......

当解密字符串时,结果是正确的(带有填充,我有一个删除填充的功能),但是如果我将测试字符串更改一个字符,我又会得到垃圾:

B�nHL�Ek    �¿?�UΣlO����OЏ�M��NO/�f.M���Lƾ�CC�Y>F��~�qd�+

这是我用来生成随 secret 钥和 IV 的 c# 代码:

更新:我现在只使用静态 key /IV,它们在这里:

Key: lkirwf897+22#bbtrm8814z5qq=498j5
IV: 741952hheeyy66#cs!9hjv887mxx7@8y

<罢工>

<罢工>
RijndaelManaged symmetricKey = new RijndaelManaged();
symmetricKey.BlockSize = 256;
symmetricKey.KeySize = 256;
symmetricKey.Padding = PaddingMode.Zeros;
symmetricKey.Mode = CipherMode.CBC;
string key = Convert.ToBase64String(symmetricKey.Key);
string IV = Convert.ToBase64String(symmetricKey.IV);

<罢工> 然后,我将 key 和 IV 保存到数据库中,以便稍后检索以进行编码/解码。

这是完整的加密类:

public static class Encryption
{
public static string Encrypt(string prm_text_to_encrypt, string prm_key, string prm_iv)
{
var sToEncrypt = prm_text_to_encrypt;

var rj = new RijndaelManaged()
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CBC,
KeySize = 256,
BlockSize = 256,
//FeedbackSize = 256
};

var key = Encoding.ASCII.GetBytes(prm_key);
var IV = Encoding.ASCII.GetBytes(prm_iv);
//var key = Convert.FromBase64String(prm_key);
//var IV = Convert.FromBase64String(prm_iv);

var encryptor = rj.CreateEncryptor(key, IV);

var msEncrypt = new MemoryStream();
var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);

var toEncrypt = Encoding.ASCII.GetBytes(sToEncrypt);

csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
csEncrypt.FlushFinalBlock();

var encrypted = msEncrypt.ToArray();

return (Convert.ToBase64String(encrypted));
}

public static string Decrypt(string prm_text_to_decrypt, string prm_key, string prm_iv)
{

var sEncryptedString = prm_text_to_decrypt;

var rj = new RijndaelManaged()
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CBC,
KeySize = 256,
BlockSize = 256,
//FeedbackSize = 256
};

var key = Encoding.ASCII.GetBytes(prm_key);
var IV = Encoding.ASCII.GetBytes(prm_iv);
//var key = Convert.FromBase64String(prm_key);
//var IV = Convert.FromBase64String(prm_iv);

var decryptor = rj.CreateDecryptor(key, IV);

var sEncrypted = Convert.FromBase64String(sEncryptedString);

var fromEncrypt = new byte[sEncrypted.Length];

var msDecrypt = new MemoryStream(sEncrypted);
var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);

csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);

return (Encoding.ASCII.GetString(fromEncrypt));
}

public static void GenerateKeyIV(out string key, out string IV)
{
var rj = new RijndaelManaged()
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CBC,
KeySize = 256,
BlockSize = 256,
//FeedbackSize = 256
};
rj.GenerateKey();
rj.GenerateIV();

key = Convert.ToBase64String(rj.Key);
IV = Convert.ToBase64String(rj.IV);
}
}

这是我用来解密数据的 PHP 代码:

    function decryptRJ256($key,$iv,$string_to_decrypt)
{
$string_to_decrypt = base64_decode($string_to_decrypt);
$rtn = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $string_to_decrypt, MCRYPT_MODE_CBC, $iv);
//$rtn = rtrim($rtn, "\0\4");
$rtn = unpad($rtn);
return($rtn);
}

function unpad($value)
{
$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
//apply pkcs7 padding removal
$packing = ord($value[strlen($value) - 1]);
if($packing && $packing < $blockSize){
for($P = strlen($value) - 1; $P >= strlen($value) - $packing; $P--){
if(ord($value{$P}) != $packing){
$packing = 0;
}//end if
}//end for
}//end if

return substr($value, 0, strlen($value) - $packing);
}

$ky = 'lkirwf897+22#bbtrm8814z5qq=498j5'; // 32 * 8 = 256 bit key
$iv = '741952hheeyy66#cs!9hjv887mxx7@8y'; // 32 * 8 = 256 bit iv

$enc = $_COOKIE["MyCookie"];

$dtext = decryptRJ256($ky, $iv, $enc);
var_dump($dtext);

我对这部分有点不确定,因为我看到的所有示例代码只是将 base64 编码的字符串直接传递给解密器,但在我的示例中,我必须在传递之前对其进行 base64_decode否则我会收到 key 和 IV 长度不正确的错误消息。

更新:我正在使用 PHP 所需格式的 ASCII 键。如果我从 RijndaelManaged 类生成 key ,它们在 PHP 端不起作用,但我可以使用已知在 PHP 端起作用的 key ,并在 RijndaelManaged C# 端使用它们。

如果我遗漏了任何相关信息,请告诉我。 TIA!

最佳答案

为了后代,我将完整的解决方案放在这里。

C# 加密类

public static class Encryption
{
public static string Encrypt(string prm_text_to_encrypt, string prm_key, string prm_iv)
{
var sToEncrypt = prm_text_to_encrypt;

var rj = new RijndaelManaged()
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CBC,
KeySize = 256,
BlockSize = 256,
};

var key = Convert.FromBase64String(prm_key);
var IV = Convert.FromBase64String(prm_iv);

var encryptor = rj.CreateEncryptor(key, IV);

var msEncrypt = new MemoryStream();
var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write);

var toEncrypt = Encoding.ASCII.GetBytes(sToEncrypt);

csEncrypt.Write(toEncrypt, 0, toEncrypt.Length);
csEncrypt.FlushFinalBlock();

var encrypted = msEncrypt.ToArray();

return (Convert.ToBase64String(encrypted));
}

public static string Decrypt(string prm_text_to_decrypt, string prm_key, string prm_iv)
{

var sEncryptedString = prm_text_to_decrypt;

var rj = new RijndaelManaged()
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CBC,
KeySize = 256,
BlockSize = 256,
};

var key = Convert.FromBase64String(prm_key);
var IV = Convert.FromBase64String(prm_iv);

var decryptor = rj.CreateDecryptor(key, IV);

var sEncrypted = Convert.FromBase64String(sEncryptedString);

var fromEncrypt = new byte[sEncrypted.Length];

var msDecrypt = new MemoryStream(sEncrypted);
var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read);

csDecrypt.Read(fromEncrypt, 0, fromEncrypt.Length);

return (Encoding.ASCII.GetString(fromEncrypt));
}

public static void GenerateKeyIV(out string key, out string IV)
{
var rj = new RijndaelManaged()
{
Padding = PaddingMode.PKCS7,
Mode = CipherMode.CBC,
KeySize = 256,
BlockSize = 256,
};
rj.GenerateKey();
rj.GenerateIV();

key = Convert.ToBase64String(rj.Key);
IV = Convert.ToBase64String(rj.IV);
}
}

PHP 解密片段

<?php
function decryptRJ256($key,$iv,$encrypted)
{
//PHP strips "+" and replaces with " ", but we need "+" so add it back in...
$encrypted = str_replace(' ', '+', $encrypted);

//get all the bits
$key = base64_decode($key);
$iv = base64_decode($iv);
$encrypted = base64_decode($encrypted);

$rtn = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, $encrypted, MCRYPT_MODE_CBC, $iv);
$rtn = unpad($rtn);
return($rtn);
}

//removes PKCS7 padding
function unpad($value)
{
$blockSize = mcrypt_get_block_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
$packing = ord($value[strlen($value) - 1]);
if($packing && $packing < $blockSize)
{
for($P = strlen($value) - 1; $P >= strlen($value) - $packing; $P--)
{
if(ord($value{$P}) != $packing)
{
$packing = 0;
}
}
}

return substr($value, 0, strlen($value) - $packing);
}
?>
<pre>
<?php

$enc = $_COOKIE["MyCookie"];

$ky = ""; //INSERT THE KEY GENERATED BY THE C# CLASS HERE
$iv = ""; //INSERT THE IV GENERATED BY THE C# CLASS HERE

$json_user = json_decode(decryptRJ256($ky, $iv, $enc), true);

var_dump($json_user);

?>

关于C#加密到PHP解密,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11873878/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com