Solved

Java Encryption Url Variable to Decrypt in C#

Posted on 2009-07-14
5
1,068 Views
Last Modified: 2013-11-07
I am trying to use your software to encrypt/decrypt the following which a client is sending me from Java and I am trying to decrypt in C#:

Information provided from the client:

Encryption mode: AES
Blocking mode: CBC
Padding mode: PKCS5PADDING

Test key:
933aeffebf46b9f5a54fee575d723283

Encrypted URL:
http://test.com/login.htm?message=bcec60d0f3c71bef2207a4d08b65bf3ec7e100f7a564ec3c5c65fbbffbb2819162d738aae003c954956e6efe5760a75be68472b3f87b335a0f1e3f8d0626c45deca8f8b7b81a2b8993c2bbc5bd7acf2e&iv=308b72a06f3770c86c2d0cafd67c54d4

message decodes to:
sid=S123456&name=Fred+Smith&usertype=BC&bucode=SW&expires=1246044953238
-----------------------------------
Additional Information:

The encrypted URL has 2 parameters:
"      message - the AES-encrypted string in hexadecimal format
"      iv - the initialization vector for this message.  NOTE: the iv will be different for each message

The decrypted message is set up like URL parameters with the values UTF-8 url-encoded :
"      sid - user's unique id
"      name - first and last
"      usertype - position code
"      bucode - business unit code
"      expires - timestamp (in milliseconds) when this message should expire

NOTES on the "expires" field:
"      The milliseconds are counted from 1/1/1970 00:00:00 GMT
"      By default, the expire time is set to 30 minutes from the point we generate the encrypted URL to account for discrepancies in system clocks.  If you want to use a national time service to ensure our clocks are synched, we could decrease the amount of time allowed before expiration.
"      If the message is decoded after the expiration time, it should be considered invalid and access should be denied.


using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
 
namespace RijndaelManaged_Examples
{
    class RijndaelMemoryExample
    {
        public static void Main()
        {
            try
            {
 
								string original = "sid=S123456&name=Fred+Smith&usertype=BC&bucode=SW&expires=1246044953238";
 
                // Create a new instance of the RijndaelManaged
                // class.  This generates a new key and initialization 
                // vector (IV).
                RijndaelManaged myRijndael = new RijndaelManaged();
 
								byte[] key = System.Text.Encoding.UTF8.GetBytes("933aeffebf46b9f5a54fee575d723283");
								myRijndael.Key = key;
 
								byte[] IV = System.Text.Encoding.UTF8.GetBytes("308b72a06f3770c86c2d0cafd67c54d4");
								//myRijndael.BlockSize = 16;
								myRijndael.IV = IV;
								myRijndael.Mode = CipherMode.CBC;
								myRijndael.Padding = PaddingMode.PKCS7;
 
                // Encrypt the string to an array of bytes.
                //byte[] encrypted = encryptStringToBytes_AES(original, myRijndael.Key, myRijndael.IV);
 
								byte[] encrypted = System.Text.Encoding.UTF8.GetBytes("bcec60d0f3c71bef2207a4d08b65bf3ec7e100f7a564ec3c5c65fbbffbb2819162d738aae003c954956e6efe5760a75be68472b3f87b335a0f1e3f8d0626c45deca8f8b7b81a2b8993c2bbc5bd7acf2e");
								
								// Convert utf-8 bytes to a string.
								string s_unicode2 = System.Text.Encoding.UTF8.GetString(encrypted);
								Console.WriteLine("Encrypted:   {0}", s_unicode2);
                // Decrypt the bytes to a string.
                string roundtrip = decryptStringFromBytes_AES(encrypted, myRijndael.Key, myRijndael.IV);
 
                //Display the original data and the decrypted data.
                Console.WriteLine("Original:   {0}", original);
                Console.WriteLine("Round Trip: {0}", roundtrip);
								Console.Read();
            }
            catch (Exception e)
            {
                Console.WriteLine("Error: {0}", e.Message);
								Console.Read();
            }
        }
 
        static byte[] encryptStringToBytes_AES(string plainText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (plainText == null || plainText.Length <= 0)
                throw new ArgumentNullException("plainText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");
 
            // Declare the stream used to encrypt to an in memory
            // array of bytes.
            MemoryStream msEncrypt = null;
 
            // Declare the RijndaelManaged object
            // used to encrypt the data.
            RijndaelManaged aesAlg = null;
 
            try
            {
                // Create a RijndaelManaged object
                // with the specified key and IV.
                aesAlg = new RijndaelManaged();
								aesAlg.BlockSize = 256;
                aesAlg.Key = Key;
                aesAlg.IV = IV;
								
								aesAlg.Mode = CipherMode.CBC;
								aesAlg.Padding = PaddingMode.PKCS7;
 
                // Create a decrytor to perform the stream transform.
                ICryptoTransform encryptor = aesAlg.CreateEncryptor(aesAlg.Key, aesAlg.IV);
 
                // Create the streams used for encryption.
                msEncrypt = new MemoryStream();
                using (CryptoStream csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
                {
                    using (StreamWriter swEncrypt = new StreamWriter(csEncrypt))
                    {
                        //Write all data to the stream.
                        swEncrypt.Write(plainText);
                    }
                }
 
            }
            finally
            {
 
                // Clear the RijndaelManaged object.
                if (aesAlg != null)
                    aesAlg.Clear();
            }
 
            // Return the encrypted bytes from the memory stream.
            return msEncrypt.ToArray();
 
        }
 
        static string decryptStringFromBytes_AES(byte[] cipherText, byte[] Key, byte[] IV)
        {
            // Check arguments.
            if (cipherText == null || cipherText.Length <= 0)
                throw new ArgumentNullException("cipherText");
            if (Key == null || Key.Length <= 0)
                throw new ArgumentNullException("Key");
            if (IV == null || IV.Length <= 0)
                throw new ArgumentNullException("Key");
 
            // Declare the RijndaelManaged object
            // used to decrypt the data.
            RijndaelManaged aesAlg = null;
 
            // Declare the string used to hold
            // the decrypted text.
            string plaintext = null;
 
            try
            {
                // Create a RijndaelManaged object
                // with the specified key and IV.
                aesAlg = new RijndaelManaged();
								aesAlg.BlockSize = 256;
                aesAlg.Key = Key;
                aesAlg.IV = IV;
 
								aesAlg.Mode = CipherMode.CBC;
								aesAlg.Padding = PaddingMode.PKCS7;
 
 
                // Create a decrytor to perform the stream transform.
                ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV);
                // Create the streams used for decryption.
                using (MemoryStream msDecrypt = new MemoryStream(cipherText))
                {
                    using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader srDecrypt = new StreamReader(csDecrypt))
 
                            // Read the decrypted bytes from the decrypting stream
                            // and place them in a string.
                            plaintext = srDecrypt.ReadToEnd();
                    }
                }
 
            }
            finally
            {
 
                // Clear the RijndaelManaged object.
                if (aesAlg != null)
                    aesAlg.Clear();
            }
 
            return plaintext;
 
        }
    }
}

Open in new window

0
Comment
Question by:smolinitek
  • 4
5 Comments
 
LVL 23

Expert Comment

by:Jens Fiederer
ID: 24859521
You definitely want to set your blocksize to 256, otherwise you will fail setting the IV.

After that....the PKCS 5 is a problem.

See

http://www.codeproject.com/KB/vb/PKSCStandard.aspx
0
 
LVL 23

Expert Comment

by:Jens Fiederer
ID: 24860213
Hmm....even using the CryptoStream directly and decoding just the first block (so padding wouldn't matter) my output has little resemblance to your original input.
0
 
LVL 23

Expert Comment

by:Jens Fiederer
ID: 24860554
OK, I don't think you should be using System.Text.Encoding.UTF8.GetBytes to get your bytes - that encodes the characters into UTF8 bytes, it does not interpret HEX bytes.   Use something like:

   byte[] FromHex(string hex)
    {
        if (hex.Length % 2 == 1)
        {
            hex = "0" + hex;
        }
        byte[] output = new byte[hex.Length / 2];
        for (int i = 0; i < hex.Length; i += 2)
        {
            output[i/2] = byte.Parse(hex.Substring(i, 2), System.Globalization.NumberStyles.HexNumber);
        }
        return output;
    }
0
 
LVL 23

Accepted Solution

by:
Jens Fiederer earned 500 total points
ID: 24860597
Yup....replace System.Text.Encoding.UTF8.GetBytes by FromHex (as above), use a BlockSize of 128 (at that size PKCS5 and PKCS7 use the same padding), and you are OK.

I get:

plaintext
"sid=S123456&name=Fred+Smith&usertype=BC&bucode=SW&expires=1246044953238"
0

Featured Post

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

If you thought ransomware was bad, think again! Doxware has the potential to be even more damaging.
Encryption for Business Encryption (https://en.wikipedia.org/wiki/Encryption) ensures the safety of our data when sending emails. In most cases, to read an encrypted email you must enter a secret key that will enable you to decrypt the email. T…
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question