0

We are implementing some kind of auto sign on in our application and got struck at decrypting something in C#, that was encrypted in java.

Basically, a Java app generates some kind of URL. When the users clicks on the link, I need to validate the query strings and if they match, let the user sign in.

Someone provided the java code. I need to convert the same code to C# because my app is in C#. I get errors when I implement it exactly in C#.

Here is the java decryption code :

String vParameter= "ksyR31QsRcbeJoysNOsAGBHajLKWsT00wavt9LJYGOMRC8zc_vqrNOeOlGHKJHIt3sLmFhDVw_JZKr4JT0H3Jj7_Di9bKNw99qCzMOKCXYM=";  //The string that nees to be decoded.
byte[] encryptedV = Base64.decodeBase64(vParameter);
String salt = “jkjkyt4”; // the i parameter - user’s id
String password = “^hjkh673!v@!a89mz+%5rT”; // application specific
MessageDigest digester = MessageDigest.getInstance("SHA-1");
digester.update((salt + password).getBytes("UTF-8"));
byte[] key = digester.digest();
SecretKeySpec secretKey = new SecretKeySpec(key, 2, 16, “AES”);
String appIV = "SampleIV"// application specific
IvParameterSpec iv= new IvParameterSpec(appIV.getBytes(“UTF-8”));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] decryptedV = cipher.doFinal(encryptedV, 0, encryptedV.length);
String v = new String(decryptedV, “UTF-8”);

Here is the corresponding C# code

        string vParameter = "ksyR31QsRcbeJoysNOsAGBHajLKWsT00wavt9LJYGOMRC8zc_vqrNOeOlGHKJHIt3sLmFhDVw_JZKr4JT0H3Jj7_Di9bKNw99qCzMOKCXYM="; //v parameter
        byte[] encryptedV = Encoding.UTF8.GetBytes(vParameter);
        String salt = "jkjkyt4"; // the i parameter - user’s id
        String password = "^hjkh673!v@!a89mz+%5rT"; // application specific
        var sha1 = SHA1Managed.Create();

        byte[] keyBytes = Encoding.UTF8.GetBytes(salt + password); //salt + password
        byte[] key = sha1.ComputeHash(keyBytes);
        byte[] finalKey = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
        String appIV = "SampleIV";
        byte[] iv = Encoding.UTF8.GetBytes(appIV); //iv
        Array.Copy(key, 2, finalKey, 0, 16); //key 2, 16
        AesManaged tdes = new AesManaged();
        tdes.Key = finalKey;
        tdes.Mode = CipherMode.CBC;
        tdes.Padding = PaddingMode.PKCS7;
        tdes.IV = iv;
        ICryptoTransform crypt = tdes.CreateDecryptor();
        byte[] cipher = crypt.TransformFinalBlock(encryptedV, 0, encryptedV.Length);
        string decryptedText = Convert.ToBase64String(cipher);
        return decryptedText;

What am I doing wrong? Can anyone point out the mistake?

EDIT : I've update the V Parameter... Note - The keys, password and IV are not real. I had to change them since I didn't want my companies keys to be public.

EDIT 2 : Hi, I've updated the vParameter.. Now they are the same. The Java code is working... It's been implemented in another app. Now, I have to create a similar version for my C# app. Can you guys point out any issues in C# code?

6
  • 2
    There are at least two mistakes in the Java code: 1) the IV is not 16 bytes (let alone random bytes) and 2) the cipher text is directly converted into a String, and UTF-8 encoding that does not encode a valid character is lost. Commented Dec 17, 2012 at 23:07
  • Instead of Encoding.UTF8.GetBytes() try, Convert.FromBase64String() for the first Base64.decodeBase64() anyway Commented Dec 17, 2012 at 23:08
  • 1
    Why are the vParameter codes different, if the password and IV isn't? You would expect a different plain text, what use is that? Commented Dec 17, 2012 at 23:08
  • 1
    You didn't just post your secret key, did you? Commented Dec 17, 2012 at 23:14
  • 1
    @BobKaufman, Nope it's public now! Commented Dec 17, 2012 at 23:17

1 Answer 1

3

You are mixing up the UTF8 en/decodings and the base64 en/decodings. Also the code as posted does not work, since the ciphertext and the IV have the wrong lengths. I suspect that is just because you changed them to avoid revealing your real data.

Anyway, here is a Java-snippet and a C#-snippet that returns the same result:

Java (I only changed vParameter and appIV into something that works):

String vParameter= "Lq4aURUiyvKvEZBWMWpUr2wRSMu96E+J1UeHLTOhKEM=";  //The string that needs to be decoded.
byte[] encryptedV = Base64.decodeBase64(vParameter.getBytes("ASCII"));
String salt = "jkjkyt4"; // the i parameter - user’s id
String password = "^hjkh673!v@!a89mz+%5rT"; // application specific
MessageDigest digester = MessageDigest.getInstance("SHA-1");
digester.update((salt + password).getBytes("UTF-8"));
byte[] key = digester.digest();
SecretKeySpec secretKey = new SecretKeySpec(key, 2, 16, "AES");
String appIV = "SampleIV12345678";// application specific
IvParameterSpec iv= new IvParameterSpec(appIV.getBytes("UTF-8"));
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
byte[] decryptedV = cipher.doFinal(encryptedV, 0, encryptedV.length);
String v = new String(decryptedV, "UTF-8");
System.out.println(v); // foobarfoobarfoobarfoobarfoobar

C# (decode vParameter using Base64 and decode the decrypted data as UTF-8. Also rename the AES object to aes instead of tdes.):

string vParameter = "Lq4aURUiyvKvEZBWMWpUr2wRSMu96E+J1UeHLTOhKEM="; //v parameter
byte[] encryptedV = Convert.FromBase64String(vParameter);
string salt = "jkjkyt4"; // the i parameter - user’s id
string password = "^hjkh673!v@!a89mz+%5rT"; // application specific
var sha1 = SHA1Managed.Create();
byte[] keyBytes = Encoding.UTF8.GetBytes(salt + password); //salt + password
byte[] key = sha1.ComputeHash(keyBytes);
byte[] finalKey = { 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8 };
string appIV = "SampleIV12345678";
byte[] iv = Encoding.UTF8.GetBytes(appIV); //iv
Array.Copy(key, 2, finalKey, 0, 16); //key 2, 16
AesManaged aes = new AesManaged();
aes.Key = finalKey;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.IV = iv;
ICryptoTransform crypt = aes.CreateDecryptor();
byte[] cipher = crypt.TransformFinalBlock(encryptedV, 0, encryptedV.Length);
string decryptedText = Encoding.UTF8.GetString(cipher);
Console.WriteLine(decryptedText); // foobarfoobarfoobarfoobarfoobar
Sign up to request clarification or add additional context in comments.

3 Comments

Hi Rasmus Faber, Thank you for the help. I was able to get further along but I get the error message 'Padding is invalid and cannot be removed.' on the crypt.TransformFinalBlock function...
@InvisibleDev: Did you get the padding error on the exact code I wrote above or when you substitute your own values?
Hi Rasmus, It works now. The IV and Key was wrong. When I replaced it with the correct values, it works now. Thanks a lot for your help on this.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.