AES encrypt / decrypt on Android does not start

I need help encrypting / decrypting an Android app.

I will explain the situation. I actually wrote an app that used content generated and encrypted by the iPhone app.

And for security, the user provides their own passphrase to properly encrypt / decrypt data between different platforms ...

But I am facing a problem with encrypting / decrypting this passphrase on Android.

I have two functions:

public byte[] crypt(String pStringToCrypt) throws Exception{

    byte[] key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    System.arraycopy(this.passphrase.getBytes(), 0, key, 0, this.passphrase.getBytes().length);
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(pStringToCrypt.getBytes());
    return encrypted;

}

      

to encrypt String and this function:

public String decrypt(byte[] pCryptedStringtoDecrypt) throws Exception{
    byte[] key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    System.arraycopy(this.passphrase.getBytes(), 0, key, 0, this.passphrase.getBytes().length);
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
    byte[] encrypted = pCryptedStringtoDecrypt;
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] original = cipher.doFinal(encrypted);
    String originalString = new String(original);
    return originalString;
}

      

to decrypt the string.

When I use the crypt method to encrypt the data, I have no error and the line was encrypted:

encrypted = [26, 119, -108, -24, 81, -128, 18, 35, -96, 10, -38, 69, 111, 40, 109, 107]

      

If I try to convert this byte to a string, I get this string:

encryptedString = "w  Q # \n Eo(mk"

      

I think the encryption phase was good. Now, when I try to decrypt this encrypted string, the application crashed:

javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
    at org.bouncycastle.jce.provider.JCEBlockCipher.engineDoFinal(JCEBlockCipher.java:711)
    at javax.crypto.Cipher.doFinal(Cipher.java:1090)
    at org.vincentsaluzzo.lightrpc.common.security.AES256.decrypt(AES256.java:61)
    at com.vincentsaluzzo.LoginBox.model.SettingsManager.getUserPassphrase(SettingsManager.java:67)
    at com.vincentsaluzzo.LoginBox.mainActivity.onCreate(mainActivity.java:26)
    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1586)
    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1638)
    at android.app.ActivityThread.access$1500(ActivityThread.java:117)
    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:928)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:123)
    at android.app.ActivityThread.main(ActivityThread.java:3647)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
    at dalvik.system.NativeStart.main(Native Method)

      

And I don't understand why this error appears ...

Do you have some solutions? or some kind of explanation for me?

+3


source to share


2 answers


Ok, with all your comments, I solved my problem.

I will explain. I changed my two methods to be as simple as possible:

public byte[] crypt(byte[] toCrypt) throws Exception {
    byte[] key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    System.arraycopy(this.passphrase.getBytes(), 0, key, 0, ((this.passphrase.getBytes().length < 16) ? this.passphrase.getBytes().length : 16));
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(toCrypt);
    return encrypted;
}

      

and

public byte[] decryptt(byte[] toDecrypt) throws Exception {
    byte[] key = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
    System.arraycopy(this.passphrase.getBytes(), 0, key, 0, ((this.passphrase.getBytes().length < 16) ? this.passphrase.getBytes().length : 16));
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");

    Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec);
    byte[] original = cipher.doFinal(toDecrypt);
    return original;
}

      



In a nutshell, I am removing all conversions to string in these methods. And I tested my methods in my other project in Objective-C. I found the problem: Encoding String!

Someday, if I encrypt / decrypt, I get the same byte array, but at one time, the array was different because I store this encrypted byte array in a String in the SharedPreference. Of course it is possible, but I just put the byte in a new string (bytes) and the base encoding is UTF-8, so that's the problem.

I allow this with base 64 encoding. I am using the Base64 class found here: http://sourceforge.net/projects/iharder/files/base64/2.3/

and before storing the encrypted byte array in SharedPreferences, I base64 encode them and the same for the decryption process.

+2


source


Generally, the usage getBytes()

for converting a string to bytes is not very good in cryptography. You are at the mercy of the default character encoding on your computer. It is much better to specify the encoding for encryption and decryption,getBytes("UTF-8")

You are not showing the calling code, are you sure you are passing a byte array ( encrypted

) to the decryption function, not a byte array string, your "w Q # \ n" Eo (mk "?



ECB mode is insecure and data leakage. For safety, you need to use CBC or CTR mode.

0


source







All Articles