Encryption JSON String - android

I want to encrypt JSON string and then send it to web server. For encryption I am using AES algorithm.
my JSON string is like :
String pJSON = "{\"UserName\":\"abc\",\"Password\":\"123456789\"}";
any idea ??

If you want to protect the password and other personal details whilst they are in transit, it is MUCH better to use HTTPS (secure HTTP) than to do your own encryption because:
If you do your own encryption/decryption then your app contains everything a hacker needs to decrypt the password, they just need to reverse-engineer it (you can make this harder, but not impossible, using a tool like Proguard)
HTTPS is designed for this type of scenario, and is much easier to implement. You just buy a secure web server cert (usually less than $100) and install it on the web server.
So I am suggesting that rather than doing your own encryption which is time-consuming and prone to attack, use the existing web infrastructure to do it for you.

Actually this is a JSON object.
You can do something like this:
JSONObject JObject=new JSONObject();
JObject.put("UserName", "abc");
JObject.put("Password", "123456789");
This will create a similar string then you can send it to server using PUT or POST method.

Please check this out. I have gone of this encryption just few day before.
public class AES_ECB {
//final static String AES_V1_KEY = "D0QgiY8JYvx8qzKx0iaN8kwEJgwpEqAJ";
final static String AES_V1_KEY = "BH&625%$#kOhrtxx";
private static final String KEY_ALGORITHM = "AES";
private static final String CIPHER_ALGORITHM = "AES/ECB/NoPadding";
// private static final String CIPHER_ALGORITHM = "AES/CFB/NoPadding";
// private static SecretKeySpec secretKeySpec = new
// SecretKeySpec(AES_V1_KEY.getBytes(), "AES");
// private static byte[] iv = "Htw%$42u&8o*pqxzV#C!33Zq29&bSq2#".getBytes();
// private static byte[] iv = new byte[] { 0x0, 0x1, 0x2, 0x3, 0x4, 0x5,
// 0x6,
// 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF };
// private static IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
private static final String PROVIDER = "BC";
static String nullPadString(String original) {
String output = original;
int remain = output.length() % 16;
if (remain != 0) {
remain = 16 - remain;
for (int i = 0; i < remain; i++)
output += (char) 0;
}
return output;
}
static String encryptString(final String RAWDATA, boolean ENCODE) {
String encrypted = null;
byte[] encryptedBytes = null;
byte[] key;
key = AES_V1_KEY.getBytes();
// SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
// Instantiate the cipher
Cipher cipher = null;
try {
String input = RAWDATA;
// KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
// SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
// sr.setSeed(key);
// kgen.init(128, sr); //192 and 256 bits may not be available
// SecretKey skey = kgen.generateKey();
// byte[] raw1 = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(key, KEY_ALGORITHM);
cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
// cipher.init(Cipher.ENCRYPT_MODE,
// AES_ECB.secretKeySpec,AES_ECB.ivParameterSpec);
// encryptedBytes = cipher.doFinal(nullPadString(input).getBytes());
encryptedBytes = cipher.doFinal(nullPadString(input).getBytes());
} catch (NoSuchAlgorithmException e) {
Log.d("ERROR", e.toString());
} catch (NoSuchPaddingException e) {
Log.d("ERROR", e.toString());
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
Log.d("ERROR", e.toString());
} catch (IllegalBlockSizeException e) {
Log.d("ERROR", e.toString());
} catch (BadPaddingException e) {
Log.d("ERROR", e.toString());
}
encrypted = new String(encryptedBytes);
if (ENCODE)
encrypted = new String(Base64.encodeBytes(encryptedBytes));
else
encrypted = new String(encryptedBytes);
return encrypted;
// /return encrypted;
}// method end
static String decryptString(final String ENCRYPTEDDATA, final boolean DECODE) {
String raw = null;
byte[] rawBytes = null;
byte[] encryptedBytes = null;
if (DECODE)
try {
encryptedBytes = Base64.decode(ENCRYPTEDDATA.getBytes());
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
else
encryptedBytes = ENCRYPTEDDATA.getBytes();
// encryptedBytes = ENCRYPTEDDATA.getBytes();
byte[] key;
key = AES_V1_KEY.getBytes();
// SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = null;
try {
// KeyGenerator kgen = KeyGenerator.getInstance(KEY_ALGORITHM);
// SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
// sr.setSeed(key);
// kgen.init(128, sr); // 192 and 256 bits may not be available
// SecretKey skey = kgen.generateKey();
// byte[] raw1 = skey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(key, KEY_ALGORITHM);
cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
rawBytes = cipher.doFinal(encryptedBytes);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(rawBytes==null)
return "";
else{
return raw = new String(rawBytes);
}
// raw = new String(rawBytes);
// int delimiter = raw.indexOf('|');
// int length = Integer.valueOf(raw.substring(0, delimiter));
// raw = raw.substring(delimiter + 1, length + delimiter + 1);
// return raw;
}
}

Related

Encrypt and save in external storage the String response of Json as a textfile

I am new in Text file Encryption in Android. And tried so many example of text encryption but i am so confused how to apply.
I have 5 string records from json response and i want to save them in a text file(in External Storage) and in "Encrypted format" . I've tried code of cipher_text_encoding but really confused with lots of classes in it.
Please suggest me either good tutorial for text encryption or give me hint how to encode.
Thanks in advance.
Encryption and Decryption using AES Secret Key Algorithm
Generate AES Secret Key:
public static byte[] generateAesSecretKey(){
String SALT2 = "strong_salt_value";
String username = "user_name";
String password = "strong_password";
byte[] key = (SALT2 + username + password).getBytes();
SecretKey secretKeySpec = null;
try {
MessageDigest sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKeySpec = new SecretKeySpec(key, "AES");
} catch (Exception e) {
e.printStackTrace();
}
return secretKeySpec.getEncoded();
}
Encryption:
public static byte[] encodeFile(byte[] secretKey, byte[] fileData) {
SecretKeySpec skeySpec = new SecretKeySpec(secretKey, "AES");
byte[] encrypted = null;
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encrypted = cipher.doFinal(fileData);
// Now write your logic to save encrypted data to sdcard here
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
return encrypted;
}
Decryption:
public static byte[] decodeFile(byte[] key, byte[] fileData) {
SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
byte[] decrypted = null;
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
decrypted = cipher.doFinal(fileData);
} catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException | BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch(Exception e){
// for all other exception
e.printStackTrace();
}
return decrypted;
}
Hope above methods are useful for you!
AS with every beginner it is normal to get confused, instead of do it yourself everything learn to leverage on code reuse or written shared libraries. This will leverage on code abstraction as you are only interested in say Encryption and Decryption of JSON/Sting.
For a Full Document:
https://docs.oracle.com/javase/8/docs/technotes/guides/security/crypto/CryptoSpec.html
For a reusable (Java/Android) library:
https://github.com/alkathirikhalid/security
Simple Usage:
String plainText = "Your String";
String encryptionKey = "Your Encryption Key";
String IV = "Your Initial Vector";
// To Encrypt
String cipherText = AES.encrypt(plainText, encryptionKey, IV);
// To Decrypt returned value same as plainText
String originalText = AES.decrypt(cipherText, encryptionKey, IV);
Cheers.

CryptoJs Encryption is not working in android

I have to implement encryption in android app. The web developer is using CryptoJs library. means Encryption alog is AES256 encryption.
Both iOS and android platforms give different strings and iOS one is accepted at web.It should be same for sample strings.
I am using below code snippets (there are 2 different diffrent functions):
private void newEnc() {
String secret = "LSC#SD2017#ps";
String cipherText = "{\"device_type\":\"iOS\",\"email\" : \"jhon#gmail.com\",\"device_id\" : \"14105DA4-CEE5-431E-96A2-2331CDA7F062\",\"password\" : \"123456\",\"device_token\" : \"B44777563552882EC3139A0317E401B55D6FC699D0AC3D279F392927CAF9B566\"}";
KeyGenerator kgen = null;
try {
kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(secret.getBytes("UTF8"));
kgen.init(256, sr);
SecretKey skey = kgen.generateKey();
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec skeySpec = new SecretKeySpec(skey.getEncoded(), "AES");
c.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] decrypted = c.doFinal(cipherText.getBytes());
System.out.println(Base64.encodeToString(decrypted, Base64.NO_WRAP));
// decrypted = Base64.encodeBase64(decrypted);
// byte[] iv = Base64.encodeBase64(c.getIV());
// Log.e("encryptString", new String(decrypted));
// Log.d("encryptString iv", new String(iv));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
}
}
I also used :
private void enctest(String cipherText) {
String secret = "LSC#SD2017#ps";
// String cipherText = "{\"device_type\":\"iOS\",\"email\" : \"jhon#gmail.com\",\"device_id\" : \"14105DA4-CEE5-431E-96A2-2331CDA7F062\",\"password\" : \"123456\",\"device_token\" : \"B44777563552882EC3139A0317E401B55D6FC699D0AC3D279F392927CAF9B566\"}";
MessageDigest md5 = null;
try {
// String cipherText = "U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hyaQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=";
byte[] cipherData = Base64.decode(cipherText.getBytes(), Base64.NO_WRAP);
byte[] saltData = Arrays.copyOfRange(cipherData, 8, 16);
md5 = MessageDigest.getInstance("MD5");
final byte[][] keyAndIV = GenerateKeyAndIV(32, 16, 1, saltData, secret.getBytes("UTF-8"), md5);
SecretKeySpec key = new SecretKeySpec(keyAndIV[0], "AES");
IvParameterSpec iv = new IvParameterSpec(keyAndIV[1]);
byte[] encrypted = Arrays.copyOfRange(cipherData, 16, cipherData.length);
Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCBC.init(Cipher.ENCRYPT_MODE, key, iv);
byte[] decryptedData = aesCBC.doFinal(cipherText.getBytes("UTF-8"));
// String plainText = "Hello, World! This is a Java/Javascript AES test.";
// SecretKey key = new SecretKeySpec(
// Base64.decodeBase64("u/Gu5posvwDsXUnV5Zaq4g=="), "AES");
// AlgorithmParameterSpec iv = new IvParameterSpec(
// Base64.decodeBase64("5D9r9ZVzEYYgha93/aUK2w=="));
// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// cipher.init(Cipher.ENCRYPT_MODE, key, iv);
// System.out.println(Base64.encodeBase64String(cipher.doFinal(
// plainText.getBytes("UTF-8"))));
// String decryptedText = new String(decryptedData, "UTF-8");
System.out.println(Base64.encodeToString(decryptedData, Base64.NO_WRAP));
// enctest(decryptedText);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
But none gives the same results.
in iOS they are using https://github.com/etienne-martin/CryptoJS.swift
What should I do that both of our encrypted strings match.
The actual cipherText (not to be confused the character string with the same variable name) is formatted and starts with "Salted__" and presumably encryption parameters. The two different functions create different outputs with different formats. They can not produce the same output.
Note 1, confusing cipherText:
// String cipherText = "{\"device_type\":\"iOS\",\"email\" : \"jhon#gmail.com\",\"device_id\" : \"14105DA4-CEE5-431E-96A2-2331CDA7F062\",\"password\" : \"123456\",\"device_token\" : \"B44777563552882EC3139A0317E401B55D6FC699D0AC3D279F392927CAF9B566\"}";
// String cipherText = "U2FsdGVkX1+tsmZvCEFa/iGeSA0K7gvgs9KXeZKwbCDNCs2zPo+BXjvKYLrJutMK+hxTwl/hyaQLOaD7LLIRo2I5fyeRMPnroo6k8N9uwKk=";
Note 2:
Base64 is so un-useful for humans, it is designed for computers, hex is for humans and computers with a direct bits to bytes correspondence.

How to truncated tag with AES GCM?

I'm using AES/GCM encryption and I'm trying to reduce tag from 128 bits to 32 bits.
I've found some documentation about GCMParameterSpec method which is supposed to do this work.
You can see my code bellow:
Cipher cipher = null;
try {
byte[] input = Utils.hexStringToByteArray("d9313225f88406e5a55909c5aff5269a");
byte[] keyByte = Utils.hexStringToByteArray("cfa2b0719afe65b60b1461cdc6a7f7e3");
SecretKeySpec key = new SecretKeySpec(keyByte, "AES");
cipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(32, Utils.hexStringToByteArray("000000000000000000000000"));
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
/*byte[] aad = Utils.hexStringToByteArray("000000");
cipher.updateAAD(aad);*/
final byte[] encrypted = new byte[cipher.getOutputSize(0)];
cipher.update(input, 0, input.length, encrypted, 0); //Not being updated for current data.
//Tag output
byte[] tag = new byte[cipher.getOutputSize(0)];
cipher.doFinal(tag, 0);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
//cipher.updateAAD(aad);
final byte[] data1 = new byte[16];
int offset = cipher.update(encrypted, 0, encrypted.length, data1, 0);
cipher.update(tag, 0, tag.length, data1, offset);
cipher.doFinal(data1,offset);
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
} catch (ShortBufferException e) {
e.printStackTrace();
}
}
It sends me this exception:
java security invalidkeyexception: Invalid value for MAC size: 32
Do you have some issue or can you explain me why it doesn't work?
Thanks.

Simple AES encryption and decryption not returning original text

I am using the following simple encrypt and decrypt functions just to see that it works before using more complicated security features like padding and hashing. For some reason the returned clear text is not similar to the original message. Here is the code:
public static byte[] encrypt(SecretKey secret, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException
{
/* Encrypt the message. */
cipher = Cipher.getInstance("AES/CTR/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] ciphertext = cipher.doFinal(buffer);
return ciphertext;
}
public static byte[] decrypt(SecretKey secret, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException
{
/* Decrypt the message. - use cipher instance created at encrypt */
cipher.init(Cipher.DECRYPT_MODE, secret);
byte[] clear = cipher.doFinal(buffer);
return clear;
}
and the calling code:
SecretKey secret1 = null;
byte[] ciphertext = null;
byte[] message = "Hello, World!".getBytes();
byte[] clear = null;
try {
// aSecret is a shared secret generated with ECDH
secret1 = Crypto.createAESKey(aSecret);
ciphertext = Crypto.encrypt(secret1, message);
clear = Crypto.decrypt(secret1, ciphertext);
String s = new String(clear);//clear.toString();
keyAText.setText(new String(message));
keyBText.setText(s);
return;
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidParameterSpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
This is almost certainly due to the fact that you don't provide an IV using IvParameterSpec during initialization. On Java SE, your code won't even run due to the fact that CTR requires this parameter to be set. Other providers may however implement things differently, e.g. they may provide a random IV instead.
Of course, if you use a different random IV during encryption and decryption, your decryption result will likely not match your plaintext.
Try the following amended methods:
public static byte[] encrypt(SecretKey secret, byte[] buffer) throws GeneralSecurityException
{
/* Encrypt the message. */
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
SecureRandom rng = new SecureRandom();
byte[] ivData = new byte[cipher.getBlockSize()];
rng.nextBytes(ivData);
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(ivData));
byte[] ciphertext = cipher.doFinal(buffer);
return Arrays.concatenate(ivData, ciphertext);
}
public static byte[] decrypt(SecretKey secret, byte[] buffer) throws GeneralSecurityException
{
/* Decrypt the message. - use cipher instance created at encrypt */
Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");
int n = cipher.getBlockSize();
byte[] ivData = Arrays.copyOf(buffer, n);
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivData));
byte[] clear = cipher.doFinal(buffer, n, buffer.length - n);
return clear;
}

Android DES Decrypt badpaddingexception: pad block corrupted

First of all, I've reviewed all the entries on the forum, and I still can not find a solution to my problem.
I have to measure the time it takes to encode and decode a text with DES, and make a comparison with other algorithms.
When I run the code, I have this error: BadPaddingException: pad block corrupted. When I debug, the code fails in this line:
  byte [] plaintext = cipher.doFinal (cipherBytes);
I use class Base64 to encode/decode String <--> byte[]
Any idea?
thanks
private static final String CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";
private static int KEY_LENGTH = 64;
public static SecretKey deriveKeyDES() {
try {
long start = System.currentTimeMillis();
KeyGenerator kgen = KeyGenerator.getInstance("DES");
kgen.init(KEY_LENGTH);
SecretKey result = kgen.generateKey();
long elapsed = System.currentTimeMillis() - start;
return result;
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
public static String encrypt(String plaintext, SecretKey key) {
try {
long start = System.currentTimeMillis();
Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding")
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] cipherText = cipher.doFinal(plaintext.getBytes("UTF-8"));
long elapsed = System.currentTimeMillis() - start;
return toBase64(cipherText);
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static String toBase64(byte[] bytes) {
return Base64.encodeToString(bytes, Base64.NO_WRAP).trim();
}
public static String decrypt(String ciphertext, SecretKey key) {
try {
byte[] cipherBytes = fromBase64(ciphertext);
long start = System.currentTimeMillis();
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
cipher.update(cipherBytes);
// This is where I get exception
byte[] plaintext = cipher.doFinal(cipherBytes);
String plainrStr = new String(plaintext, "UTF-8").trim();
long elapsed = System.currentTimeMillis() - start;
return plainrStr;
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
public static byte[] fromBase64(String base64) {
return Base64.decode(base64, Base64.NO_WRAP);
}
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, key);
cipher.update(cipherBytes);
// byte[] plaintext = cipher.doFinal(cipherBytes);
// ^-- You shouldn't pass cipherBytes twice.
// v-- instead use the parameter-less method:
byte[] plaintext = cipher.doFinal();
Padding exception occur when the last cipher text block does not compute to valid plain text. This would happen if last ciphertext block is corrupted or the key is incorrect. For CBC mode it would also happen if the second to last ciphertext was altered (but you are using ECB mode encryption).
In your case, the deriveKeyDES() is always generating a random key. Although we didn't get the actual calls to the security methods, I would presume you use a different key for encryption and decryption. In that case there is a very high chance that the resulting plain text does not contain valid padding bytes.
Rasmus answer certainly points to an error in your code, and it would screw up your timings and return a the plain text two times, but it would not remove the BadPaddingException.
I had the same problem in one source code, and IllegalBlockSizeException in another one.
Solved this two problems by return encoding data like:
public String encrypt(String input) {
try {
byte[] inputBytes = input.getBytes("UTF-8");
byte[] enc = encryptCipher.doFinal(inputBytes);
// and problem was in return encoding. That's how i fixed it
return Base64.encodeToString(enc,Base64.DEFAULT);
.....
}
}
Give u a code for decrypt:
public String decrypt(String input) {
try {
byte[] dec = Base64.decode(input.getBytes(), Base64.DEFAULT);
//here had exception
byte[] utf8 = decryptCipher.doFinal(dec);
return new String(utf8,"UTF8");
} catch (IOException | BadPaddingException | IllegalBlockSizeException e) {
e.printStackTrace();
}
return null;
}
I should submit, that had BadPaddingException and IllegalBlockSizeException
only in decrypt method byte[] utf8 = decryptCipher.doFinal(dec); (u had exeption in the same place: byte[] plaintext = cipher.doFinal(cipherBytes);), but real wrong is in encrypt method(return value)
That's why i recommend u to use that code in encrypt method:
return Base64.encodeToString(enc,Base64.DEFAULT);
P.S Tried to a give full answer on your question.

Categories

Resources