locked
Encryption using Rijndael AES using 128 bit keys, 16 byte blocks and cipher block chaining

    Question

  • I'm trying to encrypt a string (0082~1~555~5~60~2~6~3~910~20091110150514~T~125000~USD~F~375019001006800~0~0~4).  I tried using the code from obviex (http://www.obviex.com/samples/Encryption.aspx), but I do not need the password, so I modified the code to just use my key (abcdef0123456789abcdef0123456789) instead of using the password to generate a key.  I'm not getting the correct result(see below). Can someone tell what I'm doing wrong?  Is my settings not correct or am I using the wrong encryption code?  If so, do you know of one I can use?

     

    Modified coded:

    //byte[] saltValueBytes = Encoding.ASCII.GetBytes(saltValue);

     

    //PasswordDeriveBytes password = new PasswordDeriveBytes(passPhrase, saltValueBytes, hashAlgorithm,  passwordIterations);

     

    //byte[] keyBytes = password.GetBytes(keySize / 8);

     

    byte[] keyBytes = Encoding.ASCII.GetBytes(passPhrase);

     

    Calling code:

    string str = "0082~1~555~5~60~2~6~3~910~20091110150514~T~125000~USD~F~375019001006800~0~0~4";
    string passPhrase = "abcdef0123456789abcdef0123456789";
    string saltValue = "0";
    string hashAlgorithm = "SHA1";
    int passwordIterations = 1;
    string initVector = "0000000000000000";
    int keySize = 128;
          
    RijndaelSimple encrypt = new RijndaelSimple();
    string Encrypt_String = encrypt.Encrypt(str, passPhrase, saltValue, hashAlgorithm, passwordIterations, initVector, keySize);

     

     

     

    =======================================================

    Rijndael (AES) is the encryption standard using 128-bit keys, 16-byte blocks, and Cipher
    Block Chaining (CBC).

    Encryption Key = abcdef0123456789abcdef0123456789

    initialization vector: 0

    salt value = 0

    String to encrypt:  0082~1~555~5~60~2~6~3~910~20091110150514~T~125000~USD~F~375019001006800~0~0~4

    Encryption result:

    HEX -

    C3 78 CA F9 23 DD 2C A2 07 BF CF 40 1F 0A 90 58
    3E C9 33 BF EA 52 3E E2 01 45 BA C0 1A AB C5 E5
    F7 B4 9B FF E4 56 D5 FF FE D7 59 35 60 BA 31 87
    B9 00 13 67 A8 2C 08 CB 9A 96 ED EA B0 6E 71 9A

    Base 64 -

    w3jK+SPdLKIHv89AHwqQWD7JM7/qUj7iAUW6wBqrxeX3tJv/5FbV//7XWTVgujGHuQATZ6gsCMualu3qsG5xmg==

    Sunday, April 25, 2010 6:18 PM

Answers

  • People before you dump code into a topic please READ whats going on! The keys you setup are all wrong, give you ignore the CBC requirement and one of you you even calls DeriveBytes on the key!! the Topic starter gave specific input and output snippets he needs to match and neither of you even bothered to read that far into the thread! you both are anything but helpfull!

    Now back on subject here's the final program however due to the fact that the samples pad with random bytes and we use zero's the last line will not match the samples, this however should not cause any issues the other side of the conversation will still be able to decrypt it without issues.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    
    namespace ConsoleApplication4
    {
     class Program
     {
      static void Main(string[] args)
      {
       RijndaelManaged rm = new RijndaelManaged();
       byte[] Key = { 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89 };
       string str = "2~6~3~910~20091110150514~T~125000~USD~F~375019001006800~0~0~";
       byte[] data = System.Text.Encoding.ASCII.GetBytes(str);
       byte[] IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
       rm.Mode = CipherMode.CBC;
       rm.Padding = PaddingMode.Zeros;
       ICryptoTransform trans = rm.CreateEncryptor(Key,IV);
       byte[] Decrypt = trans.TransformFinalBlock(data, 0, data.Length);
       string s = System.Text.Encoding.ASCII.GetString(Decrypt);
       for (int i = 0; i < Decrypt.Length; i++)
       {
        Console.Write("{0:X2} ",Decrypt[i]);
        if (i%16 ==15)
         Console.WriteLine();
       }
      }
     }
    }
    

     

     

     

    • Marked as answer by Harry Zhu Monday, May 03, 2010 9:53 AM
    Monday, April 26, 2010 10:38 AM

All replies

  • You are making it extremly difficult to help you, "the result is wrong" tells us nothing, whats wrong with it? what where you expecing? and on a sidenote whats the point of using AES if you are not going to use a password? you might as well not encrypt!

    Sunday, April 25, 2010 6:33 PM
  • Sorry for being unclear.  I'm not very familiar with encryption so i can't give you more details than the string that I get back from the encryption does not match the result that I expected(result provided by a developer guide from Blackboard).  It's not my choice to use AES.  I'm having to encrypt my string to write to a port of Blackboard's transaction system and they require AES.  So, using the Key(abcdef0123456789abcdef0123456789) to get the KeyBytes, is not correct?  Let me know if you need more info. 

    Here is the result that I got from using the encryption code with my modification...

    0PNjvVaM1PB9GFt6lAa6OOMo0GwJyzB/ERCEWsPXj7wHa66MyvXrwES077JbZPCvqql/g6uI/ys9Hvr4CE8PY2JwtcDu2mwmS8FtBGVdwag=

    The expected result is...

    in HEX -

    C3 78 CA F9 23 DD 2C A2 07 BF CF 40 1F 0A 90 58
    3E C9 33 BF EA 52 3E E2 01 45 BA C0 1A AB C5 E5
    F7 B4 9B FF E4 56 D5 FF FE D7 59 35 60 BA 31 87
    B9 00 13 67 A8 2C 08 CB 9A 96 ED EA B0 6E 71 9A

    in Base 64 -

    w3jK+SPdLKIHv89AHwqQWD7JM7/qUj7iAUW6wBqrxeX3tJv/5FbV//7XWTVgujGHuQATZ6gsCMualu3qsG5xmg==

     

    Sunday, April 25, 2010 6:46 PM
  • Without having the guide you are looking at its difficult to tell, but given aes is a symetrical cypher (same key used for encryption and decryption) you can't just pull a key out of your behind and hope it'll work, you *HAVE* to use the same key the other side is using in the conversation.
    Sunday, April 25, 2010 7:07 PM
  • The guide that I have does not give me much details except the the details that I gave you, that's why I'm kinda stuck.  The key both sides use is "abcdef0123456789abcdef0123456789".  Does that help?

    Here is example that they provided me so I can find/write the correct encryption code.  The string is delimited by a tilda(7e) ...

      

    Transaction examples are shown using ASCII Hexadecimal notation.

    Encryption Key = abcdef0123456789abcdef0123456789

    Deposit Request Packet:

    The areas in

    italics are encrypted, the CRC is bolded (56 D8).

    15:04:10 NOV10 2009

    Transaction Request:

    30 30 38 32 7E 31 7E 35 35 35 7E 35 7E 36 30 7E

    C3 78 CA F9 23 DD 2C A2 07 BF CF 40 1F 0A 90 58

    3E C9 33 BF EA 52 3E E2 01 45 BA C0 1A AB C5 E5

    F7 B4 9B FF E4 56 D5 FF FE D7 59 35 60 BA 31 87

    B9 00 13 67 A8 2C 08 CB 9A 96 ED EA B0 6E 71 9A

    56 D8

    Decrypted:

    30 30 38 32 7E 31 7E 35 35 35 7E 35 7E 36 30 7E

    32 7E 36 7E 33 7E 39 31 30 7E 32 30 30 39 31 31

    31 30 31 35 30 35 31 34 7E 54 7E 31 32 35 30 30

    30 7E 55 53 44 7E 46 7E 33 37 35 30 31 39 30 30

    31 30 30 36 38 30 30 7E 30 7E 30 7E 3F 48 F6 5B

    56 D8

     

    Message Length 30 30 38 32 (7E) Total Length including CRC.

    Encryption 31 (7E)

    Vendor Number 35 35 35 (7E)

    Terminal Number 35 (7E)

    Encrypted Length 36 30 (7E) Length from Version Number to Cash Equivalent amount.

    Version Number 32 (7E)

    Transaction Type 36 (7E)

    Sequence Number 33 (7E)

     

    RINTED FEBRUARY 10, 2010 1-26

    Tender Number 39 31 30 (7E)

    Date/Time 32 30 30 39 31 31 31 30 31 35 30 35 31 34 (7E)

    Online Flag 54 (7E)

    Transaction Amount 31 32 35 30 30 30 (7E)

    Currency 55 53 44 (7E)

    Manual ID 46 (7E)

    Track Two Data 33 37 35 30 31 39 30 30 31 30 30 36 38 30 30 (7E)

    PIN 30 (7E)

    Cash Equiv Amount 30 (7E)

    Encryption Pad 3F 48 F6 5B

     

    Added data to bring the encrypted data block size to a value divisible

    by sixteen (60 actual data + 4 pad = 64.

    CRC is calculated after encrypting the data and includes Message Length through Encryption Pad.

    Sunday, April 25, 2010 7:28 PM
  • Although sample data helps can you post the part that told you its AES-128-CBC ? there has to be a reference to the InitalisationVector somewhere (IV) ?

    Sunday, April 25, 2010 10:26 PM
  • Here's an excerption from the developer guide for the encryption.  I think you missed the part about IV in my first message.  I can provide the full guide to you if you tell me where to send it.  Thanks for your patience and help.

    Message Encryption
    • Rijndael (AES) is the encryption standard using 128-bit keys, 16-byte blocks, and Cipher
    Block Chaining (CBC).
    – The AES initialization vector is zero.
    – For more information about encryption, go to: National Institute of Standards and Technology
    (NIST) http://www.nist.gov/
    • For code examples, go to: http://www.gladman.me.uk/

    Monday, April 26, 2010 3:58 AM
  • Must have overlooked it indeed, anyhow here you go.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    
    namespace ConsoleApplication4
    {
      class Program
      {
        static void Main(string[] args)
        {
          RijndaelManaged rm = new RijndaelManaged();
          byte[] Key = { 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89 };
          byte[] data = { 0xC3, 0x78, 0xCA, 0xF9, 0x23, 0xDD, 0x2C, 0xA2, 0x07, 0xBF, 0xCF, 0x40, 0x1F, 0x0A, 0x90, 0x58, 0x3E, 0xC9, 0x33, 0xBF, 0xEA, 0x52, 0x3E, 0xE2, 0x01, 0x45, 0xBA, 0xC0, 0x1A, 0xAB, 0xC5, 0xE5, 0xF7, 0xB4, 0x9B, 0xFF, 0xE4, 0x56, 0xD5, 0xFF, 0xFE, 0xD7, 0x59, 0x35, 0x60, 0xBA, 0x31, 0x87, 0xB9, 0x00, 0x13, 0x67, 0xA8, 0x2C, 0x08, 0xCB, 0x9A, 0x96, 0xED, 0xEA, 0xB0, 0x6E, 0x71, 0x9A };
          byte[] IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
          rm.Mode = CipherMode.CBC;
          rm.Padding = PaddingMode.None;
          ICryptoTransform trans = rm.CreateDecryptor(Key,IV);
          byte[] Decrypt = trans.TransformFinalBlock(data, 0, data.Length);
          for (int i = 0; i < Decrypt.Length; i++)
          {
            Console.Write("{0:X2} ",Decrypt[i]);
            if (i%16 ==15)
              Console.WriteLine();
          }
        }
      }
    }
    

    output :

    32 7E 36 7E 33 7E 39 31 30 7E 32 30 30 39 31 31
    31 30 31 35 30 35 31 34 7E 54 7E 31 32 35 30 30
    30 7E 55 53 44 7E 46 7E 33 37 35 30 31 39 30 30
    31 30 30 36 38 30 30 7E 30 7E 30 7E 3F 48 F6 5B

     

    Monday, April 26, 2010 4:50 AM
  • Sorry if I confused you thru all this.  I noticed that this is for decrypting.

    How do I encrypt it?  I need to encrypt the string  "2~6~3~910~20091110150514~T~125000~USD~F~375019001006800~0~0~4".  The expected result after encryption is...

    C3 78 CA F9 23 DD 2C A2 07 BF CF 40 1F 0A 90 58
    3E C9 33 BF EA 52 3E E2 01 45 BA C0 1A AB C5 E5
    F7 B4 9B FF E4 56 D5 FF FE D7 59 35 60 BA 31 87
    B9 00 13 67 A8 2C 08 CB 9A 96 ED EA B0 6E 71 9A

    Monday, April 26, 2010 5:00 AM
  • C'mon man atleast *TRY* to solve it your self, swiching the code from decryption to encryption is fairly trivial. (Hint, replace the call that says CreateDecryptor with something else)

    Whats not trivial is however the padding they use, does the document mention anything about that? they seem to have replaced the 0x34 (last char of the string) to 3F 48 F6 5B, however thats definitly not standard way of padding data. 

    Monday, April 26, 2010 5:21 AM
  • I think see below as to how to set the IV and Key. Following snippet will show you how to encrypt using RijndaelManaged.

        static void Main(string[] args)
        {
         
          SymmetricAlgorithm myAlg = new RijndaelManaged();
          
          string str = "0082~1~555~5~60~2~6~3~910~20091110150514~T~125000~USD~F~375019001006800~0~0~4";
          byte[] saltValueBytes = Encoding.ASCII.GetBytes("saltValue");
          string passPhrase = "abcdef0123456789abcdef0123456789";
    
          // Create the PasswordDeriveBytes object with the password and salt value
          PasswordDeriveBytes passwordKey = new PasswordDeriveBytes(passPhrase, saltValueBytes, "SHA1", 3);
    
          // Set key and IV for the algorithm
          myAlg.Key = passwordKey.GetBytes(myAlg.KeySize / 8);
          myAlg.IV = passwordKey.GetBytes(myAlg.BlockSize / 8);
    
    
          // Get a memory stream to write encrypted data
          using (MemoryStream encryptedData = new MemoryStream())
          {
    
            // Get encryptor
            using (CryptoStream encryptStream = new CryptoStream(encryptedData, myAlg.CreateEncryptor(), CryptoStreamMode.Write))
            {
              // Step 6: Write the contents to the CryptoStream
              encryptStream.Write(ASCIIEncoding.ASCII.GetBytes(str), 0, str.Length);
    
              // Close the file handles
              encryptStream.Close();
            }
    
    
            Console.WriteLine(Convert.ToBase64String(encryptedData.ToArray()));
            Console.ReadLine();
          }
    
        }
    
    Monday, April 26, 2010 5:26 AM
  • Sorry!  I've been working on this for a long time and just frustrated and confused to say the least.  Seems like that the way they have it set up it not typical and very unusual.

    Here's what it says about padding data...

    Encryption Pad

    Binary - 0 to 15 encryption round-up bytes.

    • Arbitrary data of sufficient length to round up encrypted data area to

    the next multiple of 16 bytes.

    Monday, April 26, 2010 5:34 AM
  • Hi,

    I provided an example. in this example you can change Key and IV as you wish, but they must be 16 unicode characters (32 bytes).

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Diagnostics;
    using System.IO;
    using System.Security.Cryptography;
    
    namespace ConsoleApplication1
    {
     class Program
     {
     static void Main(string[] args)
     {
      byte[] b = Encrypt("0082~1~555~5~60~2~6~3~910~20091110150514~T~125000~USD~F~375019001006800~0~0~4");
      Console.WriteLine(Decrypt(b));
      Console.ReadKey();
     }
     private static string Decrypt(byte[] b)
     {
      RijndaelManaged rm = null;
      MemoryStream ms = null;
      CryptoStream cs = null;
      StreamReader sr = null;
      string ret = null;
      try
      {
      rm = new RijndaelManaged();
      rm.Key = Encoding.ASCII.GetBytes("LLSeattleKey2010");//VARY IMPORTANT NOTE: Key must be 32 bytes (16 unicode characters)
      rm.IV = Encoding.ASCII.GetBytes("LL SeattleIV2010");//VARY IMPORTANT NOTE: IV must be 32 bytes (16 unicode characters)
      ICryptoTransform ict = rm.CreateDecryptor();
      ms = new MemoryStream(b);
      cs = new CryptoStream(ms, ict, CryptoStreamMode.Read);
      sr = new StreamReader(cs);
      ret = sr.ReadToEnd();
      }
      finally
      {
      if (null != sr)
       sr.Close();
      if (null != cs)
       cs.Close();
      if (null != ms)
       ms.Close();
      if (null != rm)
       rm.Clear();
      }
      return ret;
     }
     private static byte[] Encrypt(string s)
     {
      RijndaelManaged rm = null;
      MemoryStream ms = null;
      CryptoStream cs = null;
      StreamWriter sw = null;
      try
      {
      rm = new RijndaelManaged();
      rm.Key = Encoding.ASCII.GetBytes("LLSeattleKey2010");//VARY IMPORTANT NOTE: Key must be 32 byte (16 unicode character)
      rm.IV = Encoding.ASCII.GetBytes("LL SeattleIV2010");//VARY IMPORTANT NOTE: IV must be 32 byte (16 unicode character)
      ICryptoTransform ict = rm.CreateEncryptor();
      ms = new MemoryStream();
      cs = new CryptoStream(ms, ict, CryptoStreamMode.Write);
      sw = new StreamWriter(cs);
      sw.Write(s);
      }
      finally
      {
      if (null != sw)
       sw.Close();
      if (null != cs)
       cs.Close();
      if (null != ms)
       ms.Close();
      if (null != rm)
       rm.Clear();
      }
      return ms.ToArray();
     }
     }
    }
    /*OUTPUT
     * 0082~1~555~5~60~2~6~3~910~20091110150514~T~125000~USD~F~375019001006800~0~0~4
    */

    Regards,

    Yasser.


    Don't be stickler and wine with William Shakespeare after the solution :^)
    "And this our life, exempt from public haunt, finds tongues in trees, books in the running brooks, sermons in stones, and good in everything." William Shakespeare
    Monday, April 26, 2010 6:01 AM
  • People before you dump code into a topic please READ whats going on! The keys you setup are all wrong, give you ignore the CBC requirement and one of you you even calls DeriveBytes on the key!! the Topic starter gave specific input and output snippets he needs to match and neither of you even bothered to read that far into the thread! you both are anything but helpfull!

    Now back on subject here's the final program however due to the fact that the samples pad with random bytes and we use zero's the last line will not match the samples, this however should not cause any issues the other side of the conversation will still be able to decrypt it without issues.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Security.Cryptography;
    
    namespace ConsoleApplication4
    {
     class Program
     {
      static void Main(string[] args)
      {
       RijndaelManaged rm = new RijndaelManaged();
       byte[] Key = { 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01, 0x23, 0x45, 0x67, 0x89 };
       string str = "2~6~3~910~20091110150514~T~125000~USD~F~375019001006800~0~0~";
       byte[] data = System.Text.Encoding.ASCII.GetBytes(str);
       byte[] IV = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
       rm.Mode = CipherMode.CBC;
       rm.Padding = PaddingMode.Zeros;
       ICryptoTransform trans = rm.CreateEncryptor(Key,IV);
       byte[] Decrypt = trans.TransformFinalBlock(data, 0, data.Length);
       string s = System.Text.Encoding.ASCII.GetString(Decrypt);
       for (int i = 0; i < Decrypt.Length; i++)
       {
        Console.Write("{0:X2} ",Decrypt[i]);
        if (i%16 ==15)
         Console.WriteLine();
       }
      }
     }
    }
    

     

     

     

    • Marked as answer by Harry Zhu Monday, May 03, 2010 9:53 AM
    Monday, April 26, 2010 10:38 AM
  • wow, this thread is exactly what i was looking for.  stupid blackboard technical reference is worthless.

    thanks!

    Wednesday, October 10, 2012 2:09 PM