解密 PHP 中的 C# RIJNDAEL 编码文本
Decrypt C# RIJNDAEL encoded text in PHP
作为授权过程的一部分,我需要解密一个字符串。
文档指定授权字符串是使用以下设置加密的:
- 输入数据的填充:
PKCS*7
- 密码字节数组的长度为 32 个字节。密码字符串被转换为 UTF-16 编码的字节数组,然后用零填充字节数组,最多 32 个字节的长度。较长的密码将被截断。
C# 示例:
/// <summary>
/// Decrypts a string.
/// </summary>
/// <param name="content">The string to decrypt.</param>
/// <param name="password">The password to use.</param>
/// <returns>The decrypted string.</returns>
private static string DecryptString(string content, string password)
{
Rijndael aes;
byte[] retVal = null;
byte[] contentBytes;
byte[] passwordBytes;
byte[] ivBytes;
try
{
contentBytes = Convert.FromBase64String(content);
//Create the password and initial vector bytes
passwordBytes = new byte[32];
ivBytes = new byte[16];
Array.Copy(Encoding.Unicode.GetBytes(password), passwordBytes, Encoding.Unicode.GetBytes(password).Length);
Array.Copy(passwordBytes, ivBytes, 16);
//Create the cryptograpy object
using (aes = Rijndael.Create())
{
aes.Key = passwordBytes;
aes.IV = ivBytes;
aes.Padding = PaddingMode.PKCS7;
//Decrypt
retVal = aes.CreateDecryptor().TransformFinalBlock(contentBytes, 0, contentBytes.Length);
}
}
catch
{
}
return Encoding.Unicode.GetString(retVal);
}
此处讨论了相同的功能,但对于 JAVA:Decrypt C# RIJNDAEL encoded text
我尝试使用以下函数对其进行解密,但结果与预期不同:
function decrypt($string, $pass){
$iv = substr($pass, 0, 16);
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_256,
$pass,
base64_decode($string),
MCRYPT_MODE_CBC,
$iv);
$pad = ord($data[strlen($data) - 1]);
return substr($data, 0, -$pad);
}
加密后的字符串"7iTdZnp0DtGnIfwwqY4W/glbLLVZ0+asVLAuz13PzrW0wM6HC7rNuQvcG8JDSehyYeBJARdXHgLo9hRL9sBz3fN5LJ8cro3o0kFnAao2YRU="
应该解密为
"ldYWMFlSbcki6LMl3rkNfGavnt8VqmZd"
使用密码"GAT"
我觉得跟密码/iv/encoding有关系
function decrypt($string, $pass)
{
$encodedPass = mb_convert_encoding($pass, 'utf-16le');
$encodedPass = substr($encodedPass, 0, 32);
$encodedPass = str_pad($encodedPass, 32, "[=10=]", STR_PAD_RIGHT);
$iv = substr($encodedPass, 0, 16);
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,
$encodedPass,
base64_decode($string),
MCRYPT_MODE_CBC,
$iv);
$pad = ord($data[strlen($data) - 1]);
return substr($data, 0, -$pad);
}
在PHP中,MCRYPT_RIJNDAEL_128
/MCRYPT_RIJNDAEL_256
不是密钥的大小,而是块的大小(参见https://www.chilkatsoft.com/p/php_aes.asp)。 C# 通常使用 16 字节块,所以 MCRYPT_RIJNDAEL_128
。密钥的大小是自动检测的。请注意,我已将密码 的 encoding/resizing 移到 方法中。
作为授权过程的一部分,我需要解密一个字符串。
文档指定授权字符串是使用以下设置加密的:
- 输入数据的填充:
PKCS*7
- 密码字节数组的长度为 32 个字节。密码字符串被转换为 UTF-16 编码的字节数组,然后用零填充字节数组,最多 32 个字节的长度。较长的密码将被截断。
C# 示例:
/// <summary>
/// Decrypts a string.
/// </summary>
/// <param name="content">The string to decrypt.</param>
/// <param name="password">The password to use.</param>
/// <returns>The decrypted string.</returns>
private static string DecryptString(string content, string password)
{
Rijndael aes;
byte[] retVal = null;
byte[] contentBytes;
byte[] passwordBytes;
byte[] ivBytes;
try
{
contentBytes = Convert.FromBase64String(content);
//Create the password and initial vector bytes
passwordBytes = new byte[32];
ivBytes = new byte[16];
Array.Copy(Encoding.Unicode.GetBytes(password), passwordBytes, Encoding.Unicode.GetBytes(password).Length);
Array.Copy(passwordBytes, ivBytes, 16);
//Create the cryptograpy object
using (aes = Rijndael.Create())
{
aes.Key = passwordBytes;
aes.IV = ivBytes;
aes.Padding = PaddingMode.PKCS7;
//Decrypt
retVal = aes.CreateDecryptor().TransformFinalBlock(contentBytes, 0, contentBytes.Length);
}
}
catch
{
}
return Encoding.Unicode.GetString(retVal);
}
此处讨论了相同的功能,但对于 JAVA:Decrypt C# RIJNDAEL encoded text
我尝试使用以下函数对其进行解密,但结果与预期不同:
function decrypt($string, $pass){
$iv = substr($pass, 0, 16);
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_256,
$pass,
base64_decode($string),
MCRYPT_MODE_CBC,
$iv);
$pad = ord($data[strlen($data) - 1]);
return substr($data, 0, -$pad);
}
加密后的字符串"7iTdZnp0DtGnIfwwqY4W/glbLLVZ0+asVLAuz13PzrW0wM6HC7rNuQvcG8JDSehyYeBJARdXHgLo9hRL9sBz3fN5LJ8cro3o0kFnAao2YRU="
应该解密为
"ldYWMFlSbcki6LMl3rkNfGavnt8VqmZd"
使用密码"GAT"
我觉得跟密码/iv/encoding有关系
function decrypt($string, $pass)
{
$encodedPass = mb_convert_encoding($pass, 'utf-16le');
$encodedPass = substr($encodedPass, 0, 32);
$encodedPass = str_pad($encodedPass, 32, "[=10=]", STR_PAD_RIGHT);
$iv = substr($encodedPass, 0, 16);
$data = mcrypt_decrypt(MCRYPT_RIJNDAEL_128,
$encodedPass,
base64_decode($string),
MCRYPT_MODE_CBC,
$iv);
$pad = ord($data[strlen($data) - 1]);
return substr($data, 0, -$pad);
}
在PHP中,MCRYPT_RIJNDAEL_128
/MCRYPT_RIJNDAEL_256
不是密钥的大小,而是块的大小(参见https://www.chilkatsoft.com/p/php_aes.asp)。 C# 通常使用 16 字节块,所以 MCRYPT_RIJNDAEL_128
。密钥的大小是自动检测的。请注意,我已将密码 的 encoding/resizing 移到 方法中。