Android Question Help with AES encryption / decryption

DSD

Member
Licensed User
Longtime User
I'm having some trouble trying to decrypt a file (xml-based) encrypted with AES 128 bit (using C# and RijndaelManaged). Further more it uses PKCS5.

I'm not able to get this to work and have not been able to decrypt the file.

I'm using the Encryption Library written by Andrew Graham in B4A.

Here's the code I'm using (it's derived from another code posted in this forum):

B4X:
Sub Decrypt(encryptedData As String ) As String

    Dim kg As KeyGenerator
    Dim c As Cipher
    Dim B64 As Base64
    Dim Bconv As ByteConverter
    Dim data(0) As Byte
     
      Dim p As String
      Dim md As MessageDigest
         
    c.Initialize("AES/CBC/PKCS5Padding")       
    kg.Initialize("AES")
   
    p = "password"
    kg.KeyFromBytes(p.GetBytes("UTF8"))
   
    data = B64.DecodeStoB(encryptedData)
    data = c.Decrypt(data, kg.Key, False)   

    Return Bconv.StringFromBytes(data, "UTF8")

End Sub

The exception I get when trying to decrypt the file is: "java.security.InvalidKeyException, Unsupported key size: 7 bytes"

I'm obviously doing something wrong here...

Any help is appreciated.
 

DSD

Member
Licensed User
Longtime User
Your key is incorrect. An arbitrary array of bytes is not a valid key. How do you create it in C#?
Thank you for the response.
Shouldn't the key be based on the secret key, in this case "password"?

Here's the C# code that I'm using to encrypt / decrypt:

B4X:
    public static string EncryptString(string InputText, string Password)
    {
        RijndaelManaged RijndaelCipher = new RijndaelManaged();
       
        byte[] PlainText = System.Text.Encoding.Unicode.GetBytes(InputText);
        byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());

        //This class uses an extension of the PBKDF1 algorithm defined in the PKCS#5 v2.0
        //standard to derive bytes suitable for use as key material from a password.
        //The standard is documented in IETF RRC 2898.
       
        PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
        //Creates a symmetric encryptor object.
        ICryptoTransform Encryptor = RijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
        MemoryStream memoryStream = new MemoryStream();
        //Defines a stream that links data streams to cryptographic transformations
        CryptoStream cryptoStream = new CryptoStream(memoryStream, Encryptor, CryptoStreamMode.Write);
        cryptoStream.Write(PlainText, 0, PlainText.Length);
        //Writes the final state and clears the buffer
        cryptoStream.FlushFinalBlock();
        byte[] CipherBytes = memoryStream.ToArray();
        memoryStream.Close();
        cryptoStream.Close();
        string EncryptedData = Convert.ToBase64String(CipherBytes);
        return EncryptedData;

    }

    public static string DecryptString(string InputText, string Password)
    {

        RijndaelManaged  RijndaelCipher = new RijndaelManaged();
        byte[] EncryptedData = Convert.FromBase64String(InputText);
        byte[] Salt = Encoding.ASCII.GetBytes(Password.Length.ToString());
        //Making of the key for decryption
        PasswordDeriveBytes SecretKey = new PasswordDeriveBytes(Password, Salt);
        //Creates a symmetric Rijndael decryptor object.
        ICryptoTransform Decryptor = RijndaelCipher.CreateDecryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16));
        MemoryStream  memoryStream = new MemoryStream(EncryptedData);
        //Defines the cryptographics stream for decryption.THe stream contains decrpted data
        CryptoStream  cryptoStream = new CryptoStream(memoryStream, Decryptor, CryptoStreamMode.Read);
        byte[] PlainText = new byte[EncryptedData.Length];
        int DecryptedCount = cryptoStream.Read(PlainText, 0, PlainText.Length);
        memoryStream.Close();
        cryptoStream.Close();
        //Converting to string
        string DecryptedData = Encoding.Unicode.GetString(PlainText, 0, DecryptedCount);
        return DecryptedData;

    }
 
Upvote 0

DSD

Member
Licensed User
Longtime User
The key is not the same. You can see that the key is created with a salt. This is missing in your code.

When is PasswordDeriveBytes defined?

I'm sorry you are absolutely correct.
Although I'm not quite sure how to resolve this since the PasswordDeriveBytes is part of the .net framework and the System.Security.Cryptography namespace.

The C# code is a few years old, but there is xml-files encrypted with this code and I need to be able to decrypt the files using B4A...

Here's a screenshot when debuging the code and after the PasswordDeriveBytes is created.

PasswordDeriveBytes.png
 
Upvote 0

DSD

Member
Licensed User
Longtime User
The exception I keep getting is "java.security.invalidkeyexception unsupported key size", when I "google" this it seems that there are "export" restrictions in Java since the encryption is higher than 128-bit. According to the info I found, I need to download two jar-files from Oracle and somehow include these with my android application. How do I go about this?

The files in question are:

local_policy.jar
US_export_policy.jar

Any help regarding this is appreciated.
 
Upvote 0
Top