Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AES encryption/decryption between C# (encryption) and Java (decryption)

I have a C# application to calls a Java web service to validate a user's password. I'd like to have the C# application encrypt the password and then have the Java web service decrypt the password. I have the code on the Java side done (the decryption code), but I can't figure out the C# code to encrypt the code.

Here is my Java code...

public void validateUserPassword(String encryptedPassword) {
    String algorithm = "AES";
    SecretKeySpec  keySpec = null;
    byte[] key =  "<==OMGWTFBBQ!==>".getBytes();

    Cipher cipher = null;

    cipher = Cipher.getInstance(algorithm);
    keySpec = new SecretKeySpec(key, algorithm);

    byte[] encryptionBytes = new sun.misc.BASE64Decoder().decodeBuffer(encryptedPassword);      
    cipher.init(Cipher.DECRYPT_MODE, keySpec);
    byte[] recoveredBytes = cipher.doFinal(encryptionBytes);
    String recovered = new String(recoveredBytes);

    log.info("Encrypted password: " + encryptedPassword);
    log.info("Dencrypted password: " + recovered);
}

Here is something I found to encrypt using C#, but it doesn't produce the same encrypion string as my Java function so my Java web service is unable to decrypt it.

private void btnEncrypt_Click(object sender, EventArgs e)
{
    string PlainText = "testing";
    string Password = "<==OMGWTFBBQ!==>";
    string Salt = "Kosher";
    string HashAlgorithm = "SHA1";
    int PasswordIterations = 2;
    string InitialVector = "OFRna73m*aze01xY";
    int KeySize = 256;
    string encryptedPassword;

    byte[] InitialVectorBytes = Encoding.ASCII.GetBytes(InitialVector);
    byte[] SaltValueBytes = Encoding.ASCII.GetBytes(Salt);
    byte[] PlainTextBytes = Encoding.UTF8.GetBytes(PlainText);

    PasswordDeriveBytes DerivedPassword = new PasswordDeriveBytes(Password, SaltValueBytes, HashAlgorithm, PasswordIterations);

    byte[] KeyBytes = DerivedPassword.GetBytes(KeySize / 8);
    RijndaelManaged SymmetricKey = new RijndaelManaged();
    SymmetricKey.Mode = CipherMode.CBC;
    byte[] CipherTextBytes = null;

    using (ICryptoTransform Encryptor = SymmetricKey.CreateEncryptor(KeyBytes, InitialVectorBytes))
    {
        using (MemoryStream MemStream = new MemoryStream())
        {
            using (CryptoStream CryptoStream = new CryptoStream(MemStream, Encryptor, CryptoStreamMode.Write))
            {
                CryptoStream.Write(PlainTextBytes, 0, PlainTextBytes.Length);
                CryptoStream.FlushFinalBlock();
                CipherTextBytes = MemStream.ToArray();
                MemStream.Close();
                CryptoStream.Close();
            }
        }
    }
    SymmetricKey.Clear();
    encryptedPassword = Convert.ToBase64String(CipherTextBytes);

    MessageBox.Show("Encrypted password: " + encryptedPassword);
}

I don't mind changing the way my Java web service decrypts in order to make it work with my C# application.

like image 204
Steve B Avatar asked Dec 22 '22 07:12

Steve B


1 Answers

In C# you are using a DeriveBytes function to get your key from the password, while in Java you are using the password directly as key.

This way you obviously have a different key on both sides. Don't do this, use the same key derivation function on both sides.

like image 162
Paŭlo Ebermann Avatar answered Dec 24 '22 02:12

Paŭlo Ebermann