【发布时间】:2015-05-12 05:58:42
【问题描述】:
从用 .NET 编写的 Web 服务接收参数,但我无法解密这些
参数已使用 SHA1,Rijndael 256 位加密。
php代码:
$passphrase='16charskey';
$salt = '16charssat';
$iterations = 2;
$keysize = 32;
$key = pbkdf2($passphrase,$salt, $iterations, $keysize);
$text = 'my crypted text';
$iv = '16charsinitvector';
$result = mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, base64_decode($text), MCRYPT_MODE_CBC, $iv)
函数 pbkdf2 是下一个
function pbkdf2( $p, $s, $c, $kl, $a = 'sha1' ) {
$hl = strlen(hash($a, null, true)); # Hash length
$kb = ceil($kl / $hl); # Key blocks to compute
$dk = ''; # Derived key
# Create key
for ( $block = 1; $block <= $kb; $block ++ ) {
# Initial hash for this block
$ib = $b = hash_hmac($a, $s . pack('N', $block), $p, true);
# Perform block iterations
for ( $i = 1; $i < $c; $i ++ )
# XOR each iterate
$ib ^= ($b = hash_hmac($a, $b, $p, true));
$dk .= $ib; # Append iterated block
}
# Return derived key of correct length
return substr($dk, 0, $kl);
}
当我执行时给出警告: mcrypt_encrypt():IV参数必须和
中的blocksize一样长我测试了将 $iv 的长度更改为 32 个字符并且警告消失了。当我将字符串 $iv 更改为任何小于 32 个字符的字符串时,结果与 $iv 为空时相同。
有什么想法吗?
更新
这是加密中的WebService代码
Public Function strEncrypt( _
ByVal strText As String _
, ByVal strPass As String _
, ByVal strSalt As String _
, ByVal strHASH As String _
, ByVal nIterations As Integer _
, ByVal strIV As String _
, ByVal nSize As Integer _
) As String
Try
Dim btText As Byte() = Encoding.UTF8.GetBytes(strText)
Dim btSalt As Byte() = Encoding.UTF8.GetBytes(strSalt)
Dim btIV As Byte() = Encoding.UTF8.GetBytes(strIV)
Dim objPasswordDeriveBytes As PasswordDeriveBytes = New PasswordDeriveBytes(strPass, btSalt, strHASH, nIterations)
Dim btKey As Byte() = objPasswordDeriveBytes.GetBytes(nSize / 8)
Dim objRijndaelManaged As RijndaelManaged = New RijndaelManaged()
objRijndaelManaged.Mode = CipherMode.CBC
Dim objICryptoTransform As ICryptoTransform = objRijndaelManaged.CreateEncryptor(btKey, btIV)
Dim objMemoryStream As MemoryStream = New MemoryStream()
Dim objCryptoStream As CryptoStream = New CryptoStream(objMemoryStream, objICryptoTransform, CryptoStreamMode.Write)
objCryptoStream.Write(btText, 0, btText.Length)
objCryptoStream.FlushFinalBlock()
Dim btEncrypt As Byte() = objMemoryStream.ToArray()
objMemoryStream.Close()
objCryptoStream.Close()
strEncrypt = Convert.ToBase64String(btEncrypt)
Catch ex As Exception
strEncrypt = ""
End Try
编辑
我将 pbkdf2 调用更改为 pbkdf1
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;
}
MCRYPT_RIJNDAEL_128 的算法是正确的,但是 mcrypt_encrypt 的输出和 web 服务对于相同的字符串,具有相同的盐、迭代、密钥大小、密码,是不同的......
我看不出获得不同输出的区别
【问题讨论】:
-
您确定 .net 网络服务使用 Rijndael 256 而不仅仅是 AES 256? IV 也必须与密文一起出现。您不能只使用任何 IV。
-
我不确定,我用网络服务中的 .net 代码更新了帖子,谢谢!!!
-
我已经回滚了最新的更改。你不应该从根本上改变问题本身。 StackOverflow 不是在线调试器。检查函数的输入/输出!例如。 PBKDF2 的输出在两个运行时都不会相同,您可以打印出十六进制值并进行比较。
-
对不起,你是对的。但是我在 pbkdf2(和 pbkdf1)中的两个运行时都得到相同的输出,我不知道我是否在执行中出错
-
已解决:此 php 代码对我有用 stackoverflow.com/a/22920556/4654981
标签: c# php encryption sha1 mcrypt