[英].NET WebService encrypt -> PHP decrypt error: mcrypt_encrypt(): The IV parameter must be as long as the blocksize in
從.NET中編寫的Web服務接收參數,但是我無法解密這些參數
參數已使用Rijndael 256位SHA1加密。
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參數的長度必須與
我測試了將$ 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服務的輸出是截然不同的...
我看不出獲得獨特輸出的區別
Artjom是正確的,您應該將MCRYPT_RIJNDAEL_256
替換為MCRYPT_RIJNDAEL_128
。
請注意,使用靜態IV是不安全的。 但是,它比在傳輸協議中使用CBC模式加密要安全得多(因為沒有完整性保護,並且因為可能使用填充預言); 僅當攻擊者無法更改密文時,才應使用這種方案。
編輯之后,您還可以清楚地實現了PBKDF2,而不是PasswordDeriveBytes
提供的PBKDF1。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.