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 数学建模招标中位数问题
  • ¥15 phython路径名过长报错 不知道什么问题
  • ¥15 深度学习中模型转换该怎么实现
  • ¥15 HLs设计手写数字识别程序编译通不过
  • ¥15 Stata外部命令安装问题求帮助!
  • ¥15 从键盘随机输入A-H中的一串字符串,用七段数码管方法进行绘制。提交代码及运行截图。
  • ¥15 TYPCE母转母,插入认方向
  • ¥15 如何用python向钉钉机器人发送可以放大的图片?