Rijndael/AES解密C#到PHP的转换

Rijndael/AES解密C#到PHP的转换,c#,php,aes,rijndaelmanaged,rijndael,C#,Php,Aes,Rijndaelmanaged,Rijndael,我有下面的C代码# 此代码段解密某个文件并输出解密版本。在RijndaelManaged im的CreateDecryptor方法中,使用密码作为密钥和IV 我在这里找到了一些关于stackoverflow for PHP的代码,但是如果我尝试像C#一样为key和iv提供相同的字节数组,那么什么都不会发生 $Pass = "hellowld"; $Clear = file_get_contents('./file.dat', FILE_USE_INCLUDE_PATH); $bytePass=

我有下面的C代码#

此代码段解密某个文件并输出解密版本。在RijndaelManaged im的CreateDecryptor方法中,使用密码作为密钥和IV

我在这里找到了一些关于stackoverflow for PHP的代码,但是如果我尝试像C#一样为key和iv提供相同的字节数组,那么什么都不会发生

$Pass = "hellowld";
$Clear = file_get_contents('./file.dat', FILE_USE_INCLUDE_PATH);

$bytePass=array();
$i = 0;
foreach (str_split($Pass) as $value) {
    $bytePass[$i]=ord($value);
    $i++;
}

echo decryptAES($Clear,$bytePass,$bytePass);

function decryptAES($content,$iv, $key,$aes) {

// Setzt den Algorithmus
switch ($aes) {
    case 128:
       $rijndael = 'rijndael-128';
       break;
    case 192:
       $rijndael = 'rijndael-192';
       break;
    default:
       $rijndael = 'rijndael-256';
}

// Setzt den Verschlüsselungsalgorithmus
// und setzt den Output Feedback (OFB) Modus
$cp = mcrypt_module_open($rijndael, '', 'ofb', '');

 // Ermittelt die Anzahl der Bits, welche die Schlüssellänge des Keys festlegen
$ks = mcrypt_enc_get_key_size($cp);

// Erstellt den Schlüssel, der für die Verschlüsselung genutzt wird
$key = substr(md5($key), 0, $ks);

// Initialisiert die Verschlüsselung
mcrypt_generic_init($cp, $key, $iv);

// Entschlüsselt die Daten
$decrypted = mdecrypt_generic($cp, $content);

// Beendet die Verschlüsselung
mcrypt_generic_deinit($cp);

// Schließt das Modul
mcrypt_module_close($cp);

return trim($decrypted);

}
我真的需要一些帮助如何正确地在PHP中创建代码。我没有必要用PHP输出一个文件,一个字符串就足够了

更新: 默认的C#RijndaelManaged密码方法是AES-128-CBC。我将PHP代码更改为mcrypt模块()

更新2: 我确实成功地创建了一个Java解密程序,这让我想到了另一件事。PHP必须使用PKCS7填充。

您的C#代码看起来并不安全,因此如果您可以更改它,请参阅下面的一些提示。 下面是您给定的PHP代码,经过修改后看起来可能与给定的C#代码等效

function decryptAES128CBC($content,$iv, $key) {

    // AES is Rijndael-128
    $rijndael = 'rijndael-128';

    // key size is 128 bit = 16 bytes
    $ks = 16;

    // CBC mode, not OFB
    $cp = mcrypt_module_open($rijndael, '', 'cbc', '');

    // pad key and IV by zeros (this is not a good idea)
    $key = str_pad($key, $ks, "\0");
    $iv = str_pad($key, $iv, "\0");

    // initialize the decryptor with key and IV
    mcrypt_generic_init($cp, $key, $iv);

    // the actual work
    $decrypted = mdecrypt_generic($cp, $content);

    // clean up
    mcrypt_generic_deinit($cp);
    mcrypt_module_close($cp);

    // remove padding, see below
    return unpad($decrypted);
}
最后一个
unpad
用于删除可能由加密功能附加的填充,以将消息大小扩大到完整的块数。RijndaelManaged使用的默认填充是PKCS7填充,它附加了大量字节(介于1到16之间),每个字节等于附加的字节数。在实际的实现中,您将在解密后检查填充是否有效(即,所有这些字节都具有相同的值),但对于“快速和脏”,您可以简单地使用检查最后一个字节并删除那么多字节的内容。有关示例,请参见

如果您可以更改您的C代码:

  • 请注意,使用固定值(每个键)作为初始化向量通常不是一个好主意,使用键本身作为初始化向量也不是一个好主意。使用随机初始化向量(与消息一起发送),或查看下一点

  • 此外,您通常不希望将(相当短的)密码直接用作密钥,而是使用较长的密码短语,并使用salt(包含在消息中)对其进行哈希以派生密钥。如果执行此操作,还可以从相同的两个数据段派生初始化向量(但使用键派生函数,它们会有所不同)。 为了避免从加密文件中强行输入密码,请在此处使用慢速哈希函数(PBKDF-2或bcrypt)

您的C#代码看起来并不安全,因此如果您可以更改它,请参阅下面的一些提示。 下面是您给定的PHP代码,经过修改后看起来可能与给定的C#代码等效

function decryptAES128CBC($content,$iv, $key) {

    // AES is Rijndael-128
    $rijndael = 'rijndael-128';

    // key size is 128 bit = 16 bytes
    $ks = 16;

    // CBC mode, not OFB
    $cp = mcrypt_module_open($rijndael, '', 'cbc', '');

    // pad key and IV by zeros (this is not a good idea)
    $key = str_pad($key, $ks, "\0");
    $iv = str_pad($key, $iv, "\0");

    // initialize the decryptor with key and IV
    mcrypt_generic_init($cp, $key, $iv);

    // the actual work
    $decrypted = mdecrypt_generic($cp, $content);

    // clean up
    mcrypt_generic_deinit($cp);
    mcrypt_module_close($cp);

    // remove padding, see below
    return unpad($decrypted);
}
最后一个
unpad
用于删除可能由加密功能附加的填充,以将消息大小扩大到完整的块数。RijndaelManaged使用的默认填充是PKCS7填充,它附加了大量字节(介于1到16之间),每个字节等于附加的字节数。在实际的实现中,您将在解密后检查填充是否有效(即,所有这些字节都具有相同的值),但对于“快速和脏”,您可以简单地使用检查最后一个字节并删除那么多字节的内容。有关示例,请参见

如果您可以更改您的C代码:

  • 请注意,使用固定值(每个键)作为初始化向量通常不是一个好主意,使用键本身作为初始化向量也不是一个好主意。使用随机初始化向量(与消息一起发送),或查看下一点

  • 此外,您通常不希望将(相当短的)密码直接用作密钥,而是使用较长的密码短语,并使用salt(包含在消息中)对其进行哈希以派生密钥。如果执行此操作,还可以从相同的两个数据段派生初始化向量(但使用键派生函数,它们会有所不同)。 为了避免从加密文件中强行输入密码,请在此处使用慢速哈希函数(PBKDF-2或bcrypt)


如果有帮助,请参阅文档。如果有帮助的话,这里是文档。非常感谢您的详细回答。我无法更改C代码,但php代码的信息足以解决我的问题。这真的很有帮助。非常感谢你的详细回答。我无法更改C代码,但php代码的信息足以解决我的问题。这真的很有帮助。