VinothKathir
VinothKathir

Reputation: 200

AES encryption/decryption from c# to java

I'm using AES encryption/decryption algorithm in my application.

On the server side I use c# to encrypt/decrypt the data.

And on client side(android) I use java to decrypt the data.

C# encryption/decryption code

    static readonly string PasswordHash = "52";

    static readonly string SaltKey = "dfkjsadfinewdfadsfkmeoinmsdflksdflk";

    static readonly string VIKey = "@EUBRHDFBFG8867";

public static string Encrypt(string plainText)
    {
        byte[] plainTextBytes = Encoding.UTF8.GetBytes(plainText);

        byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash,Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);

        var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding =PaddingMode.Zeros };

        var encryptor = symmetricKey.CreateEncryptor(keyBytes,Encoding.ASCII.GetBytes(VIKey));
        byte[] cipherTextBytes;

        using (var memoryStream = new MemoryStream())
        {
            using (var cryptoStream = new CryptoStream(memoryStream, encryptor,CryptoStreamMode.Write))
            {
                cryptoStream.Write(plainTextBytes, 0, plainTextBytes.Length);
                cryptoStream.FlushFinalBlock();
                cipherTextBytes = memoryStream.ToArray();
                cryptoStream.Close();
            }
            memoryStream.Close();
        }           
       return Convert.ToBase64String(cipherTextBytes);
    }

    public static string Decrypt(string encryptedText)
    {
        byte[] cipherTextBytes = Convert.FromBase64String(encryptedText);

        byte[] keyBytes = new Rfc2898DeriveBytes(PasswordHash,Encoding.ASCII.GetBytes(SaltKey)).GetBytes(256 / 8);

        var symmetricKey = new RijndaelManaged() { Mode = CipherMode.CBC, Padding =PaddingMode.None }

        var decryptor = symmetricKey.CreateDecryptor(keyBytes,Encoding.ASCII.GetBytes(VIKey));

        var memoryStream = new MemoryStream(cipherTextBytes);

        var cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read);

        byte[] plainTextBytes = new byte[cipherTextBytes.Length];

        int decryptedByteCount = cryptoStream.Read(plainTextBytes, 0, plainTextBytes.Length);

        memoryStream.Close();
        cryptoStream.Close();

        return Encoding.UTF8.GetString(plainTextBytes, 0, decryptedByteCount).TrimEnd("\0".ToCharArray());
    }

Java Decryption method

public String decrypt(String dataToDecrypt) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException, IllegalBlockSizeException, BadPaddingException, InvalidAlgorithmParameterException, UnsupportedEncodingException 
{

    byte[] encryptedCombinedBytes = Base64.decodeBase64(dataToDecrypt.getBytes());

    String saltKey = "dfkjsadfinewdfadsfkmeoinmsdflksdflk";
    String password = "52";
    String IVKey = "@EUBRHDFBFG8867";

    PBKDF2Parameters p = new PBKDF2Parameters("HmacSHA256", "ASCII", saltKey.getBytes(), 8);

    byte[] mEncryptedPassword = new PBKDF2Engine(p).deriveKey(password);


    byte[] ivbytes = Arrays.copyOfRange(IVKey.getBytes(), 0, 16);

    SecretKeySpec mSecretKeySpec = new SecretKeySpec(mEncryptedPassword, "AES");

    Cipher mCipher = Cipher.getInstance("AES/CBC/NoPadding");

    mCipher.init(Cipher.DECRYPT_MODE, mSecretKeySpec, new IvParameterSpec(ivbytes));

    byte[] encryptedTextBytes = Arrays.copyOfRange(encryptedCombinedBytes, 16, encryptedCombinedBytes.length);

    byte[] decryptedTextBytes = mCipher.doFinal(encryptedTextBytes);

    return new String(decryptedTextBytes, "UTF-8");
}

C# decryption method works fine and give the result string.

I cannot figure out the problem in Java decryption code. It runs and give me some garbage value.

EDIT

  1. I can not edit anything on the server side.I just have to replicate the decryption in java decryption.
  2. I dont know how to use passwordHash, saltKey and IVkey

Upvotes: 2

Views: 1138

Answers (1)

Maarten Bodewes
Maarten Bodewes

Reputation: 94058

First of all, you've switched the password and the salt around.

Second, PBKDF2 uses HMAC/SHA-1 as default. As far as I know that's also the default for Rfc2898DeriveBytes:

Implements password-based key derivation functionality, PBKDF2, by using a pseudo-random number generator based on HMACSHA1.

You should also never call getBytes without specifying the character set in Java, but this is probably not an issue for your current runtime.


These are comments on the code only; do not use CBC over network connections without integrity/authenticity protection.

Upvotes: 1

Related Questions