当前位置: 首页 > 知识库问答 >
问题:

.NET Web 服务加密 -> PHP 解密错误: mcrypt_encrypt(): IV 参数必须与

贾越
2023-03-14

从.NET中写入的Web服务接收参数,但我无法解密这些参数

这些参数已经用SHA1 Rijndael 256位加密。

语法:

  $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);
}

当 i 执行时,给出警告:mcrypt_encrypt():IV 参数必须与 块大小一样长

我测试了将$iv的长度更改为32个字符,警告消失。当我将字符串$iv更改为任何少于32个字符的字符串时,结果与$iv为空时相同。

有什么想法吗?

更新

这是加密中的web服务代码

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服务的输出对于相同的字符串,具有相同的盐,迭代,键大小,密码,是不同的...

我看不出获得不同输出有什么不同

共有1个答案

傅阿苏
2023-03-14

Artjom是对的,你应该把< code>MCRYPT_RIJNDAEL_256换成< code>MCRYPT_RIJNDAEL_128。

请注意,使用静态IV并不安全。然而,它比在传输协议中使用CBC模式加密要安全得多(因为没有完整性保护,也因为填充预言机是可能的);这种方案只能在攻击者无法更改密文的情况下使用。

编辑后,很明显您已经实现了PBKDF2而不是密码字节提供的PBKDF1。

 类似资料:
  • 问题内容: 我在下面的(E.1)中使用它来进行我的应用程序,显然我认识并理解了其中的一个巨大的安全漏洞。我对加密越来越感兴趣,并且想更好地理解它,我需要随IV一起生成一个随机密钥,但是不确定如何正确地执行此操作。有人可以向我解释一下熟悉AES加密的工作原理(IV和KEY)吗? )因此,我将来能够更好地理解并可以运用我的知识,本质上,我只是想使代码更安全,谢谢。 (E.1) 问题答案: AES密钥仅

  • 我在下面(E.1)中使用它作为我的应用程序,显然有一个我认识和理解的巨大的明显的安全漏洞。我对加密越来越感兴趣,想更好地理解它,我需要生成一个随机密钥和一个IV,但不确定如何正确地执行。有人能向我解释一下熟悉AES加密的人是如何工作的吗? (E.1)

  • 我阅读了一些有关使用Java密码加密和解密数据的示例。例如: 我有2个关于解密过程的问题。 虽然IV是必需的,但我们可以使用将其保留为隐式。将自动对其应用随机IV。但是,在解密模式下,必须使用相同的IV。它是否只表示<code>密码。init(int opmode,Key Key,AlgorithmParameters params)应该使用,IV应该从加密中获取,存储并传递到这里 除了“KeyG

  • 本文向大家介绍PHP加密解密函数详解,包括了PHP加密解密函数详解的使用技巧和注意事项,需要的朋友参考一下 分享一个PHP加密解密的函数,此函数实现了对部分变量值的加密的功能。 加密代码如下: 解密代码如下: 辅助函数: 使用如下所示: 以上就是为大家分享的php加密解密函数,希望大家喜欢,可以应用到自己的学习中。

  • 本文向大家介绍php基于mcrypt_encrypt和mcrypt_decrypt实现字符串加密解密的方法,包括了php基于mcrypt_encrypt和mcrypt_decrypt实现字符串加密解密的方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了php基于mcrypt_encrypt和mcrypt_decrypt实现字符串加密解密的方法。分享给大家供大家参考,具体如下: 由于出于安

  • 问题内容: 我找到了在PHP中对字符串进行编码/解码的示例。起初它看起来非常好,但是不会起作用:-( 有人知道问题出在哪里吗? 结果是: 加密: 解密: 问题答案: 并且 在您的代码中未定义。查看有效的解决方案( 但不安全! ): 停! 这个例子是 不安全的! 不要使用它! **但是此代码中还有其他问题,使其变得不安全,尤其是使用ECB(这不是_加密_模式,只能在其上定义加密模式的构造块)。