0

Receive parameters from a web service writen in .NET but i cant decrypt these

The parameters have been encrypted with SHA1, Rijndael 256 bits.

php code:

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

the function pbkdf2 is the next

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

When i execute give the Warning: mcrypt_encrypt(): The IV parameter must be as long as the blocksize in

i tested change the length of $iv to 32 chars and the warning disappear. When i change the string $iv to other string with any string less than 32 chars, the result is the same that if $iv is empty.

any ideas?

UPDATED

This is the WebService code in the encrypt

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

EDIT

I change the pbkdf2 call to 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;
}

And the algorithm to MCRYPT_RIJNDAEL_128, that is the correct, but the output of mcrypt_encrypt and the web service for the same string, with the same salt, iterations, keysize, passphrase, is distinct...

i dont see the difference to get distinct outputs

Antonio
  • 51
  • 1
  • 1
  • 5
  • 1
    Are you sure that the .net webservice uses Rijndael 256 and not simply AES 256? The IV also must come along with the ciphertext. You can't just use any IV. – Artjom B. Mar 10 '15 at 18:41
  • i'm not sure, i updated the post with the .net code in the web service, thanks!!! – Antonio Mar 11 '15 at 10:56
  • I've rolled back the latest changes. You should not change the question itself fundamentally. StackOverflow is not an online debugger. Check the input/output of your functions! E.g. the output of PBKDF2 will never have been the same for both runtimes, you can print out values in hex and compare. – Maarten Bodewes Mar 11 '15 at 12:52
  • I'm sorry, you're right. But i get the same output for both runtimes in pbkdf2 (and pbkdf1), i dont know if i make an error in execution – Antonio Mar 11 '15 at 15:17
  • SOLVED: This php code worked for me http://stackoverflow.com/a/22920556/4654981 – Antonio Mar 18 '15 at 12:59

1 Answers1

1

Artjom is right, you should replace MCRYPT_RIJNDAEL_256 with MCRYPT_RIJNDAEL_128.

Note that using a static IV is not secure. It is however much more secure than using CBC mode encryption in a transport protocol (because there is no integrity protection and because padding oracles are possible); this kind of scheme should only be used if an attacker cannot change the ciphertext.


After the edit it has also become clear that you've implemented PBKDF2 instead of PBKDF1 provided by PasswordDeriveBytes.

Maarten Bodewes
  • 90,524
  • 13
  • 150
  • 263
  • In this Web Service, a potential attacker can't change the ciphertext. But thanks for the info, i'm not sure, i updated the post with the code of the web service encryption. thank you, everything you comment me is useful – Antonio Mar 11 '15 at 10:58
  • with MCRYPT_RIJNDAEL_128 the warning disappear, but the encryption not the same that web service. The developer of web service says me that is "Rijndael (AES) 256 bits" – Antonio Mar 11 '15 at 11:07