我如何把这个C#Rijndael加密到PHP? [英] How do I convert this C# Rijndael encryption to PHP?

查看:166
本文介绍了我如何把这个C#Rijndael加密到PHP?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有已经在SO一些有用的问题:

There are already some helpful questions on SO:

  • Rijndael 256 Encrypt/decrypt between c# and php?
  • Rewrite Rijndael 256 C# Encryption Code in PHP
  • Rijndael/AES decryption C# to PHP conversion

不过,我仍然有我的具体情况困难。

However I am still having difficulties with my particular case.

我已经试过各种方法,但最终得到的误差的IV参数必须是只要块大小或文字不结果散列匹配

I've tried various methods but end up getting the error "The IV parameter must be as long as the blocksize" or text that doesn't match the resulting hash.

我不明白加密足够的工作出了什么我做错了。

I don't understand encryption enough to work out what I'm doing wrong.

下面是PHP的版本:

$pass = 'hello';
$salt = 'application-salt';

echo Encrypt('hello', 'application-salt');

function Encrypt($pass, $salt)
{
    $derived = PBKDF1($pass, $salt, 100, 16);
    $key = bin2hex(substr($derived, 0, 8));
    $iv = bin2hex(substr($derived, 8, 8));
    return mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $pass, MCRYPT_MODE_CBC, $iv);
}

function PBKDF1($pass, $salt, $count, $dklen)
{
    $t = $pass.$salt;
    $t = sha1($t, true);
    for($i=2; $i <= $count; $i++)
    {
        $t = sha1($t, true);
    }
    $t = substr($t,0,$dklen-1);
    return $t;
}

和C#版本:

Console.WriteLine(Encrypt("hello", "application-salt"));
// output: "Hk4he+qKGsO5BcL2HDtbkA=="

public static string Encrypt(string clearText, string Password)
{
    byte[] clearData = System.Text.Encoding.Unicode.GetBytes(clearText);
    PasswordDeriveBytes pdb = new PasswordDeriveBytes(Password,
        new byte[] { 0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 });

    MemoryStream ms = new MemoryStream();
    Rijndael alg = Rijndael.Create();
    alg.Key = pdb.GetBytes(32);
    alg.IV = pdb.GetBytes(16);
    CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
    cs.Write(clearData, 0, clearData.Length);
    cs.Close();
    byte[] encryptedData = ms.ToArray();

    return Convert.ToBase64String(encryptedData);
}

我希望能够验证用户登录一个新的基于php的应用程序,这将作为现有C#应用程序相同的MySQL数据库进行通信。我打算加密密码并将所得的散列与存储在数据库中的验证之一。

I want to be able to validate user logins in a new php-based application which will communicate to the same MySQL database as an existing C# application. I intend to encrypt the password and compare the resulting hash to the one stored in the database to authenticate.

任何指针将是最AP preciated。

Any pointers would be most appreciated.

编辑:

我意识到,在C#中的功能, PasswordDeriveBytes 被调用并传递一个字节数组作为参数,对此我没有在PHP版本的模拟。我发现这从 $ C $的CProject例如,并在ASCII字节数组法术伊万梅德韦杰夫的人我认为是例如作者。不幸的是我无法改变这一点。

I realize that in the C# function, the PasswordDeriveBytes is being called and passed a byte array as an argument for which I don't have an analog in the PHP version. I discovered that this originates from a Codeproject example and that the byte array in ASCII spells "Ivan Medvedev" whom I assume to be the example author. Unfortunately I cannot change this.

推荐答案

我认为PHP版本实际上可能增加00H值字节的密钥和IV。他们都有一个无效的大小:每个8个字节。它们需要被扩展到16字节的AES-128。在C#code使用32个字节为重点,因此将使用AES使用的键大小为256位

I think that the PHP version may actually add 00h valued bytes to the key and IV. They both have an invalid size : 8 bytes for each. They need to be extended to 16 bytes for AES-128. In your C# code you use 32 bytes for the key, which will therefore use AES with a key size of 256 bits.

Futhermore,你不指定迭代次数在 PasswordDeriveBytes ,你应该将它指定为类不指定迭代的默认数量 - 根据您的意见,这将是100,让我们假设它是。

Futhermore, you don't specify the number of iterations in PasswordDeriveBytes, you should specify it as the class does not specify the default number of iterations - according to your comments, this would be 100, lets assume it is.

哦,你使用不正确的加密方法。 MCRYPT_RIJNDAEL_256使用的块大小的256位,没有的的256位指定Rijndael算法。 presumably,按键的bitsize是关键倍的字节简单地数8

Oh, and you use the incorrect encryption method. MCRYPT_RIJNDAEL_256 specifies the Rijndael algorithm using a blocksize of 256 bits, not keys of 256 bits. Presumably, the bitsize of the keys is simply the number of bytes of the key times 8.

难道你这个替换你的加密功能,然后再试一次?

Could you replace your Encrypt function with this and try again?

function Encrypt($pass, $salt)
{
     $derived = PBKDF1($pass, $salt, 100, 48);
     $key = bin2hex(substr($derived, 0, 32));
     $iv = bin2hex(substr($derived, 32, 16));
     return mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, $pass, MCRYPT_MODE_CBC, $iv);
}

最后,请检查是否产生IV和关键的比赛在PHP中的那些进行加密或解密之前。你肯定认为PHP函数PBKDF1是正确的?

Finally, please check if the generated IV and key match with the ones in PHP before performing encryption or decryption. Are you sure that that PHP PBKDF1 function is correct?

更新:
这里是M $ PBKDF1套路一些更多的信息在PasswordDeriveBytes(包括Java code,你可以尝试和转换):

UPDATE: Here is some more information on the M$ PBKDF1 routines in PasswordDeriveBytes (including Java code which you may try and convert):

哈哈,我明白你的意思。

ha, I see your point.

有趣的是,使用.NET:调用48时,结果是不同的
  或致电其次是16 32:

Interestingly, using .NET: the results are different when calling 48 or calling 32 followed by 16:

.NET GetBytes会(32 +16):
  04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA4

.NET GetBytes( 32 +16 ): 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922655D8DD89AE1CAAC60A8041FCD7E8DA4

.NET GetBytes会(32)
  04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922
  其次是GetBytes会(16)89946D3662B3196860A8041FCD7E8DA4

.NET GetBytes( 32 ) 04DD9D139DCB9DE889946D3662B319682159FF9C9B47FA15ED205C7CAF890922 Followed by GetBytes( 16 ) 89946D3662B3196860A8041FCD7E8DA4

微软真code和他们不能改变它,因为它可以打破场上的应用程序。需要注意的是,他们有16个,然后8个字节或直接由24个字节的设计的调用时,它也将返回不同的结果。你最好升级到PBKDF2,并保持PBKDF1限制为20个字节最多,如在标准中定义。

True Microsoft code, and they cannot change it because it could break applications in the field. Note that they also would return different results when calling it with 16 and then 8 bytes or directly by 24 bytes by design. You'd better upgrade to PBKDF2, and keep PBKDF1 limited to 20 bytes max, as defined in the standards.

这篇关于我如何把这个C#Rijndael加密到PHP?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆