Archived Forum Post

Index of archived forum posts

Question:

Decrypting AES 128 cipher text with 16 byte IV in C# .NET using crypt2

Dec 01 '14 at 09:09

So, I'm having trouble figuring out what I need to do to get my IV correct when deccrypting with:

CryptAlgorithm = "aes"; CipherMode = "cbc"; KeyLength = 128; PaddingScheme = 3; EncodingMode = "hex"; key = "&=*FS6wksG@Zs3qG"; (ascii encoding)

Also, during encryption i'm generating a random IV.

So, I can encrypt a string with IV and then immediately decrypt it to get the correct plainText back. But I want to be grabbing stuff from a connection and decrypt it, so I can keep all the settings the same except for the IV...which would need to change for each plainText I receive (cause it's random).

I'm currently doing this by grabbing the first 16 bytes of the plainText and trying to re-encode it and set the IV. It's just not correct. Not sure what I'm missing.

Here's my code.
The decryption in the mcrypt_encrypt() function produces the correct results.
In the mcrypt_decrypt function if I do not change the IV I get the correct results. Any attempt of mine to encode the IV correctly from cipherText is completely wrong.

Any type of help is welcome.

Note: I guess a better way of putting this is: given the full cipherText, how to encode the correct IV to decrypt correctly.

public string mcrypt_encrypt(string plainText)
    {
        //Get a new randomized IV every time we encrypt
        crypt.RandomizeIV();

        string cipherText;
        //  Do 128-bit AES encryption:
        cipherText = crypt.EncryptStringENC(plainText);

        string decoded = crypt.DecryptStringENC(cipherText);

        byte[] myText = Encoding.UTF8.GetBytes(cipherText);

        return Convert.ToBase64String(myText);            
    }

    public string mcrypt_decrypt(string cipher_text)
    {
         byte[] cipher_dec = Convert.FromBase64String(cipher_text);

         string cipher_str = Encoding.UTF8.GetString(cipher_dec);
        ;
        crypt.SetEncodedIV(cipher_str.Substring(0, 16), "hex");

         return crypt.DecryptStringENC(cipher_str);
    }

And the settings I use for both functions.

        //  AES is also known as Rijndael.
        crypt.CryptAlgorithm = "aes";

        //  CipherMode may be "ecb" or "cbc"
        crypt.CipherMode = "cbc";

        //  KeyLength may be 128, 192, 256
        crypt.KeyLength = 128;

        //  Pad with NULL bytes (PHP pads with NULL bytes)
        crypt.PaddingScheme = 3;

        //  EncodingMode specifies the encoding of the output for
        //  encryption, and the input for decryption.
        //  It may be "hex", "url", "base64", or "quoted-printable".
        crypt.EncodingMode = "hex";

        //  The secret key must equal the size of the key.  For
        //  256-bit encryption, the binary secret key is 32 bytes.
        //  For 128-bit encryption, the binary secret key is 16 bytes.
        string keyAscii;
        keyAscii = @"&=*FS6wksG@Zs3qG";
        crypt.SetEncodedKey(keyAscii, "ascii");
        crypt.KeyLength = 128;

Accepted Answer

A couple of things:

Something like this works in my limited test (VB6 code):

Option Explicit

Private Function InitCkCrypt() As ChilkatCrypt2
   Set InitCkCrypt = New ChilkatCrypt2

Dim l_Key As String

With InitCkCrypt
      .UnlockComponent "***"

'  AES is also known as Rijndael.
      .CryptAlgorithm = "aes"

'  CipherMode may be "ecb" or "cbc"
      .CipherMode = "cbc"

'  KeyLength may be 128, 192, 256
      .KeyLength = 128

'  Pad with NULL bytes (PHP pads with NULL bytes)
      .PaddingScheme = 3

'  EncodingMode specifies the encoding of the output for
      '  encryption, and the input for decryption.
      '  It may be "hex", "url", "base64", or "quoted-printable".
      .EncodingMode = "base64"

'  The secret key must equal the size of the key.  For
      '  256-bit encryption, the binary secret key is 32 bytes.
      '  For 128-bit encryption, the binary secret key is 16 bytes.
      .KeyLength = 128

.SetEncodedKey "&=*FS6wksG@Zs3qG", "ascii"
   End With
End Function

Public Function mcrypt_encrypt(ByVal plainText As String) As String
   Dim lo_Crypt As ChilkatCrypt2

Set lo_Crypt = InitCkCrypt

With lo_Crypt
      'Get a new randomized IV every time we encrypt
      .RandomizeIV

'  Do 128-bit AES encryption (prepending IV)
      mcrypt_encrypt = .GetEncodedIV("base64") & .EncryptStringENC(plainText)
   End With
End Function

Public Function mcrypt_decrypt(ByVal encryptedText As String) As String
   Dim lo_Crypt As ChilkatCrypt2
   Dim l_Iv As String

Set lo_Crypt = InitCkCrypt

With lo_Crypt
      l_Iv = Left$(encryptedText, 24)  ' Get prepended Base64 IV
      encryptedText = Mid$(encryptedText, 25)   ' Get encrypted text without prepended IV

.SetEncodedIV l_Iv, "base64"
      mcrypt_decrypt = .DecryptStringENC(encryptedText)
   End With
End Function