duanjiagu0655 2016-02-26 01:24
浏览 153

PHP使用密码和盐来获得C#Rfc2898DeriveBytes(AES256)的IV和Key替代方案

I want to regenerate my IV and Key from the password and salt I have stored. In my C# program I do It in the following way :

//passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);

The code for this is PHP returning is return a different IV and Key :

<?php
include("enctest_inc.php");

$password = "mypassword";
$salt = "mysalthereitis";

$hasher = "SHA256";
$iterations = 1000;
$keysize = 256;
$ivsize = 128;

$out = pbkdf2($hasher, $password, base64_decode($salt), $iterations, ($keysize+$ivsize)/8, true);

// split key and IV
$key = substr($out, 0, $keysize/8);
$iv = substr($out, $ivsize/8);

// print for demonstration purposes
echo base64_encode($key);
echo "<br>";
echo base64_encode($iv);
echo '<br>';
echo '<br>';

echo 'KEY : LNY893Wa00onNQh4ignFdjaVkg6GdxomMZoR/axB+Mw='; //KEY FROM SSH PROGRAM WHICH IS THE RIGHT RETURN;
echo '<br>';
echo 'IV : //QxQj7PDMRE1YUVo+mJvQ==' //IV FROM SSH PROGRAM WHICH IS THE RIGHT RETURN;

I really wonder where the problem lays or how to debug this ?

The settings are in both PHP and C# the same :

PHP CODE :

$hasher = "SHA256";
$iterations = 1000;
$keysize = 256;
$ivsize = 128;

C# CODE :

string random_string_pwd = "mypassword";
byte[] passwordBytes = Encoding.UTF8.GetBytes(random_string_pwd);

//var random_salt = new ClientTools();
//string random_string_salt = random_pwd.RndStrings(15);
string random_string_salt = "mysalthereitis";
byte[] Salt = Encoding.UTF8.GetBytes(random_string_salt);

// Hash the password with SHA256
passwordBytes = SHA256.Create().ComputeHash(passwordBytes);
AES.KeySize = 256;
AES.BlockSize = 128;

var key = new Rfc2898DeriveBytes(passwordBytes, saltBytes, 1000);
AES.Key = key.GetBytes(AES.KeySize / 8);
AES.IV = key.GetBytes(AES.BlockSize / 8);
  • 写回答

1条回答 默认 最新

  • douba1617 2016-02-26 15:14
    关注

    In PHP you Base64 decode the salt but it is not base64 encoded:
    base64_decode($salt)

    In C# you just get the bytes of the salt:
    byte[] Salt = Encoding.UTF8.GetBytes(random_string_salt);

    In PHP you are using SHA256
    In C# you are using MSN Rfc2898DeriveBytes which uses SHA1:
    Rfc2898DeriveBytes Class specifies: using a pseudo-random number generator based on HMACSHA1.
    Using SHA256 on password bytes does not fix the MSN rfc2898derivebytes. This is an MSN issue since it does not allow the HAMC to be specified.

    The solution is to change the PHP to just get the string bytes as data, not to try and Base64 decode something that is not Base64 encoded.

    1. At a minimum do the same thing in each language
    2. If you need to use the MSN Rfc2898DeriveBytes then change the PHP HMAC to SHA1.
    3. Do not Base64 decode a string that is not Base64 encoded, this will often fail. In fact Base64 decoding mysalthereitis"
    评论

报告相同问题?

悬赏问题

  • ¥15 素材场景中光线烘焙后灯光失效
  • ¥15 请教一下各位,为什么我这个没有实现模拟点击
  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 保护模式-系统加载-段寄存器