Android AES encryption - The constructor Base64() is not visible - android

I have found 2 AES encryption/decryption functions and I want to use them inside my app, but I get an error.
The functions are:
private static final String password = "test";
private static String salt;
private static int pswdIterations = 65536 ;
private static int keySize = 256;
private byte[] ivBytes;
////////////////
//encrypt AES///
////////////////
public String encrypt(String plainText) throws Exception {
//get salt
salt = generateSalt();
byte[] saltBytes = salt.getBytes("UTF-8");
// Derive the key
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
//encrypt the message
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
return new Base64().encodeAsString(encryptedTextBytes);
}
#SuppressWarnings("static-access")
public String decrypt(String encryptedText) throws Exception {
byte[] saltBytes = salt.getBytes("UTF-8");
byte[] encryptedTextBytes = new Base64().decodeBase64(encryptedText);
// Derive the key
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
// Decrypt the message
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));
byte[] decryptedTextBytes = null;
try {
decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return new String(decryptedTextBytes);
}
public String generateSalt() {
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
random.nextBytes(bytes);
String s = new String(bytes);
return s;
}
My error is at line:
return new Base64().encodeAsString(encryptedTextBytes);
and
byte[] encryptedTextBytes = new Base64().decodeBase64(encryptedText);
The error msg is : The constructor Base64() is not visible
Any idea why this happens?

Related

Android javax.crypto.BadPaddingException

I am implementing encryption/decryption to my files. code is given below. I can't find out the problem.
Am I missing anything? I need to implement 128 bit AES Encryption.
Is there anything wrong?
It end up with error
"javax.crypto.BadPaddingException: error:1e06b065:Cipher functions:EVP_DecryptFinal_ex:BAD_DECRYPT"
Please help me.
private static byte[] encodeFile(byte[] yourKey, byte[] fileData)
throws Exception {
byte[] encrypted = null;
SecretKeySpec skeySpec = new SecretKeySpec(yourKey, 0, yourKey.length, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
encrypted = cipher.doFinal(fileData);
return encrypted;
}
private static byte[] generateKey() throws NoSuchAlgorithmException {
byte[] keyStart = "This is my key".getBytes();
String id = "dummypass";
int iterationCount = 1000;
int saltLength = 32;
int keyLength = 128;
SecureRandom random = new SecureRandom();
byte[] salt = Arrays.copyOf(keyStart,saltLength);
random.nextBytes(salt);
KeySpec keySpec = new PBEKeySpec(id.toCharArray(), salt,
iterationCount, keyLength);
SecretKeyFactory keyFactory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
byte[] keyBytes = new byte[0];
try {
keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
}
SecretKey key = new SecretKeySpec(keyBytes, "AES");
return key.getEncoded();
}
private static byte[] decodeFile(byte[] yourKey, byte[] encryptedData)
throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(yourKey, 0, yourKey.length,
"AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7PADDING");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encryptedData);
return decrypted;
}
public static void Encrypt(byte[] bytesToEncrypt, File target) {
try {
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(target));
byte[] key = generateKey();
byte[] encryptedBytes = encodeFile(key, bytesToEncrypt);
bos.write(encryptedBytes);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public static byte[] DecryptFile(byte[] bytesToDecrypt) {
byte[] decodedData = new byte[0];
try {
byte[] key = generateKey();
decodedData = decodeFile(key, bytesToDecrypt);
} catch (Exception e) {
e.printStackTrace();
}
return decodedData;
}
Verify that key is the same in both Encrypt and DecryptFile.
Since both call generateKey and generateKey calls SecureRandom nextBytes the keys are going to be different.
You need to save the encryption key for use during decryption.

Android and node.js ENCRYPTION DECRYPTION by AES using SALT+PASSWORD+VECTOR (IV)

How to encrypt and decrypt a string in android using AES with Salt+password+iv . I want code equivalent to https://stackoverflow.com/a/27893935/5582162. This link has working code for node.js and iOS but I want same/equivalent code in android format.
Using the above link --
Eg:
RawData: pravin
password: sbifast12
salt: gettingsaltyfoo!
iv: QmBSbUZMUwld31DPrqyVSA==
Encrypted Key should be: AbvDUXUG9p1ysz1a1ZANSA==
Code that I tried:
try {
// byte[] salt = generateSalt();
byte[] salt = saltStr.getBytes();
// Log.i(TAG, "Salt: " + salt.length + " " + HexEncoder.toHex(salt));
PBEKeySpec pbeKeySpec = new PBEKeySpec(password.toCharArray(), salt, PBE_ITERATION_COUNT, 128);
SecretKeyFactory factory = SecretKeyFactory.getInstance(PBE_ALGORITHM);
SecretKey tmp = factory.generateSecret(pbeKeySpec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
byte[] key = secret.getEncoded();
//Log.i(TAG, "Key: " + HexEncoder.toHex(key));
// PBEParameterSpec pbeParamSpec = new PBEParameterSpec(salt, ITERATION_COUNT);
Cipher encryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM);
// byte[] encryptionSalt = generateSalt();
// Log.i(TAG, "Encrypted Salt: " + encryptionSalt.length + " " + HexEncoder.toHex(encryptionSalt));
// PBEParameterSpec pbeParamSpec = new PBEParameterSpec(encryptionSalt, 1000);
// byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
Log.i(TAG, encryptionCipher.getParameters() + " ");
// byte[] iv = generateIv();
//byte[] iv ="QmBSbUZMUwld31DPrqyVSA==".getBytes();
IvParameterSpec ivspec = new IvParameterSpec(Arrays.copyOf(iv,16));
encryptionCipher.init(Cipher.ENCRYPT_MODE, secret, ivspec);
byte[] encryptedText = encryptionCipher.doFinal(plainText.getBytes());
// Log.i(TAG, "Encrypted: " + new String(encryptedText));
Log.i(TAG, "Encrypted: " + Base64.encodeToString(encryptedText, Base64.DEFAULT));
Cipher decryptionCipher = Cipher.getInstance(CIPHER_ALGORITHM);
decryptionCipher.init(Cipher.DECRYPT_MODE, secret, ivspec);
byte[] decryptedText = decryptionCipher.doFinal(encryptedText);
Log.i(TAG, "Decrypted....: " + new String(decryptedText));
} catch (Exception e) {
e.printStackTrace();
}
And also...
public class AesEncryption2 {
private static String password = "sbifast12";
/**
* vector array for encryption & decryption
*/
private static byte[] iv = "QmBSbUZMUwld31DPrqyVSA==".getBytes();
private static String IV = "QmBSbUZMUwld31DPrqyVSA==";
private static String salt = "gettingsaltyfoo!";
private static String CIPHERTEXT = "CIPHERTEXT!";
public static void main(String rawData) {
byte[] interop_iv = Base64.decode(IV, Base64.DEFAULT);
// byte[] iv = null;
byte[] ciphertext;
SecretKeySpec secret=null;
try {
secret = generateKey(password.toCharArray(), salt.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
Map result = null;
try {
result = encrypt(rawData, iv, secret);
} catch (Exception e) {
e.printStackTrace();
}
ciphertext = (byte[]) result.get(CIPHERTEXT);
iv = (byte[]) result.get(IV);
System.out.println("Cipher text:" + Base64.encode(ciphertext, Base64.DEFAULT));
System.out.println("IV:" + Base64.encode(iv, Base64.DEFAULT) + " (" + iv.length + "bytes)");
System.out.println("Key:" + Base64.encode(secret.getEncoded(), Base64.DEFAULT));
try {
System.out.println("Deciphered: " + decrypt(ciphertext, iv, secret));
} catch (Exception e) {
e.printStackTrace();
}
// Interop demonstration. Using a fixed IV that is used in the C#
// example
try {
result = encrypt(rawData, interop_iv, secret);
} catch (Exception e) {
e.printStackTrace();
}
ciphertext = (byte[]) result.get(CIPHERTEXT);
iv = (byte[]) result.get(IV);
String text = Base64.encodeToString(ciphertext, Base64.DEFAULT);
System.out.println();
System.out.println("--------------------------------");
System.out.println("Interop test - using a static IV");
System.out.println("The data below should be used to retrieve the secret message by the receiver");
System.out.println("Cipher text: " + text);
System.out.println("IV: " + Base64.encodeToString(iv, Base64.DEFAULT));
try {
decrypt(Base64.decode(text, Base64.DEFAULT), iv, secret);
} catch (Exception e) {
e.printStackTrace();
}
}
public static SecretKeySpec generateKey(char[] password, byte[] salt) throws Exception {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password, salt, 1024, 128);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(tmp.getEncoded(), "AES");
return secret;
}
public static Map encrypt(String cleartext, byte[] iv, SecretKeySpec secret) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
// If the IvParameterSpec argument is omitted (null), a new IV will be
// created
cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(iv));
AlgorithmParameters params = cipher.getParameters();
byte[] usediv = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] ciphertext = cipher.doFinal(cleartext.getBytes("UTF-8"));
Map result = new HashMap();
result.put(IV, usediv);
result.put(CIPHERTEXT, ciphertext);
return result;
}
public static String decrypt(byte[] ciphertext, byte[] iv, SecretKeySpec secret) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
String plaintext = new String(cipher.doFinal(ciphertext), "UTF-8");
return plaintext;
}
Third method:
private static final String ALGO = "AES";
/**
* key value for encryption & decryption
*/
private static String password = "sbifast12";
private static byte[] iv = "QmBSbUZMUwld31DPrqyVSA==".getBytes();
private static String IV = "QmBSbUZMUwld31DPrqyVSA==";
private static String salt = "gettingsaltyfoo!";
/**
* constructor with two variable parameters
* #param password
* #param iv
*/
/* public AESEncryption(String password, String iv) {
if (password == null || iv == null)
throw new NullPointerException("Encryption values can not be null!");
this.password = password.getBytes();
this.iv = iv.getBytes();
}*/
/**
* encrypt given string data
*
* #param rawdata
* #return
* #throws Exception
*/
public static String encrypt(String rawdata) throws Exception {
if (rawdata == null)
throw new NullPointerException("Raw data can not be null!");
//SecretKeySpec sKey = (SecretKeySpec) generateKeyFromPassword(password, saltBytes);
//SecretKey key = new SecretKeySpec(Base64.decode(salt,Base64.DEFAULT), "AES");
// Key key = generateKey();
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
/* cipher.init(Cipher.ENCRYPT_MODE, generateKeyFromPassword("sbifast12", salt.getBytes()),
new IvParameterSpec(Arrays.copyOf(IV.getBytes("UTF-8"), 16)));
*/
cipher.init(Cipher.ENCRYPT_MODE, generateKeyFromPassword("sbifast12", salt.getBytes()),
new IvParameterSpec(Arrays.copyOf(IV.getBytes(),16)));
byte[] encVal = cipher.doFinal(rawdata.getBytes());
String encryptedValue = Base64.encodeToString(encVal, Base64.DEFAULT);
System.out.println("%%%%%%% Encrypted Text: " + encryptedValue);
return encryptedValue;
}
public static SecretKey generateKeyFromPassword(String password, byte[] saltBytes) throws GeneralSecurityException {
KeySpec keySpec = new PBEKeySpec(password.toCharArray(), saltBytes, 1000, 128);
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
// SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("PBKDF2WithSHA256AND256BITAES");
SecretKey secretKey = keyFactory.generateSecret(keySpec);
return new SecretKeySpec(secretKey.getEncoded(), "AES");
}
/**
* decrypt given string data
*
* #param encryptedData
* #return
* #throws Exception
*/
public String decrypt(String encryptedData) throws Exception {
if (encryptedData == null)
throw new NullPointerException("Encrypted data can not be null!");
Key key = generateKey();
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
byte[] decodedValue = Base64.decode(encryptedData, Base64.DEFAULT);
byte[] decValue = cipher.doFinal(decodedValue);
String decryptedValue = new String(decValue);
return decryptedValue;
}
/**
* key generator
*
* #return
* #throws Exception
*/
private Key generateKey() throws Exception {
Key key = new SecretKeySpec("sbifast12".getBytes(), ALGO);
return key;
}
public class Cryptography {
private static final String TAG = "Cryptography";
//secretKey64 is genereated from salt and password..!!! (taken directly from server side)
private static String secretKey64 = "*****1hrHpnONd8ZJ*****c756ikDmZU1v*****8Xjg=";
private static String secretKeyAlgorithm = "AES";
private static String cipherAlgorithm = "AES/CBC/PKCS7Padding";
private static String iv64 = "QmBSbU*****d31DPr*****==";
private static String charsetName = "UTF-8";
// private static int base64Mode = android.util.Base64.DEFAULT;
private static int base64Mode = android.util.Base64.NO_WRAP;
public static String encrypt(String plainText) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException
, IllegalBlockSizeException, BadPaddingException {
String encrytedText = "";
if (plainText == null) {
return null;
} else {
SecretKey secretKey = new SecretKeySpec(android.util.Base64.decode(secretKey64, 0), secretKeyAlgorithm);
IvParameterSpec iv = new IvParameterSpec(android.util.Base64.decode(iv64, 0));
Cipher cipher = Cipher.getInstance(cipherAlgorithm);
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
byte[] dataBytes = plainText.getBytes(charsetName);
encrytedText = Base64.encodeToString(cipher.doFinal(dataBytes), base64Mode);
}
// Log.d(TAG, "ENCRYPT >>>> : " + encrytedText);
return encrytedText;
}
public static String decrypt(String encryptedText) throws NoSuchAlgorithmException, NoSuchPaddingException,
InvalidKeyException, InvalidAlgorithmParameterException, UnsupportedEncodingException
, IllegalBlockSizeException, BadPaddingException, NullPointerException {
String plainText = "";
SecretKey secretKey = new SecretKeySpec(android.util.Base64.decode(secretKey64, 0), secretKeyAlgorithm);
IvParameterSpec iv = new IvParameterSpec(android.util.Base64.decode(iv64, 0));
byte[] dataBytesD = Base64.decode(encryptedText, base64Mode);
Cipher cipherD = Cipher.getInstance(cipherAlgorithm);
cipherD.init(2, secretKey, iv);
//Log.d(TAG, "DECRYPT text:- >>>> : " + encryptedText);
byte[] dataBytesDecrypted = cipherD.doFinal(dataBytesD);
try {
plainText = new String(dataBytesDecrypted);
} catch (NullPointerException e) {
e.printStackTrace();
}
//Log.d(TAG, "DECRYPT >>>> : " + plainText);
return plainText;
}
}

Cipher decode returns me an empty Array in Android

I want to encode and decode a File in Android but when i try to decrypt some File it returns an empty array of bytes.
The class I use to encrypt the File and decrypt:
public class CrytedClass {
public static byte[] generateKey(String pass) throws Exception{
byte [] start = pass.getBytes("UTF-8");
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(start);
kgen.init(128,sr);
SecretKey skey = kgen.generateKey();
return skey.getEncoded();
}
public static byte[] encodedFile(byte[] key, byte[] fileData)throws Exception{
SecretKeySpec skeySpec = new SecretKeySpec(key,"AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE,skeySpec);
byte [] encrypted = cipher.doFinal(fileData);
return encrypted;
}
public static byte[] decodeFile(byte[] key, byte[] fileData) throws Exception{
SecretKeySpec skeySpec = new SecretKeySpec(key,"AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE,skeySpec);
byte [] decrypted = cipher.doFinal(fileData);
return decrypted;
}
public static String generatePass(){
return new BigInteger(130, new SecureRandom()).toString(32);
}
public static byte[] createHas(byte[] ficheroEncrip){
MessageDigest msd = null;
try{
msd = MessageDigest.getInstance("SHA-1");
}catch (Exception e){
return null;
}
msd.update(ficheroEncrip);
return msd.digest();
}
}
The test code i use.
try {
String id1 = CrytedClass.generatePass();
byte[] secure = CrytedClass.generateKey(id1);
byte[] FileEncoded = CrytedClass.encodedFile(secure, ous.toByteArray());
byte[] decoded = CrytedClass.decodeFile(secure, FileEncoded);
File decodedFile = new File(Environment.getExternalStorageDirectory()+"/decoded.pdf");
FileOutputStream pdfFile = new FileOutputStream(decodedFile);
pdfFile.write(decoded);
System.out.println("Final del test");
Boolean r = pdfFile.equals(original);
}catch(Exception e){
}
Thanks for your help

AES encryption on android

I have to encrypt and decrypt text on android devices. I have found some solution, but when I encrypt the text again, the result is different. Can anyone tell me why?
Here is my code:
public class AESDemo {
private static final String password = "test";
private static String salt;
private static int pswdIterations = 65536;
private static int keySize = 256;
private byte[] ivBytes;
public String encrypt(String plainText) throws Exception {
//get salt
salt = generateSalt();
byte[] saltBytes = salt.getBytes("UTF-8");
// Derive the key
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
//null,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
//encrypt the message
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
ivBytes = params.getParameterSpec(IvParameterSpec.class).getIV();
byte[] encryptedTextBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
//return new Base64().encodeAsString(encryptedTextBytes);
return Base64.encodeToString(encryptedTextBytes, Base64.DEFAULT);
}
#SuppressWarnings("static-access")
public String decrypt(String encryptedText) throws Exception {
byte[] saltBytes = salt.getBytes("UTF-8");
//byte[] encryptedTextBytes = new Base64().decodeBase64(encryptedText);
byte[] encryptedTextBytes= Base64.decode(encryptedText, Base64.DEFAULT);
// Derive the key
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec spec = new PBEKeySpec(
password.toCharArray(),
saltBytes,
pswdIterations,
keySize
);
SecretKey secretKey = factory.generateSecret(spec);
SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
// Decrypt the message
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes));
byte[] decryptedTextBytes = null;
try {
decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
return new String(decryptedTextBytes);
}
public String generateSalt() {
SecureRandom random = new SecureRandom();
byte bytes[] = new byte[20];
String ss = "";
random.nextBytes(bytes);
String s = new String(bytes);
return "sare";
}
}
I've hardcoded the salt to be the same, but the result is different every time. Can anyone tell me why?
Your IV handling puzzles me. You call getIV() but where do you actually set the IV for the encryption? It seems to me you are using a random IV which might explain why you get a different encrypted data each time.
I would suggest to try create a dynamic IvParameterSpec class and fill it with a preset IV.

Cannot Decrypt AES on Android?

I'm a newbie to android dev, right now I implemented an AES on Android and it could encrypt strings with user input passwords. The encryption seems fine and it could omit Base64/Hex encoded strings.
But When I try to decrypt it, the problem comes: With the decryption, the omission always showing me a load of messy characters.
In order to get rid of it, I've tried debugging it by define a charset (Like UTF-8) while casting from string to byte[], but no hit, and also tried to encode the omit with base 64 or Hex, but both of them failed.
I've also tried to define AES/CBC/PKCS5Padding or just AES while using cipher.getInstance method, but still no go.
It is quite irritating, could you guys help me please?
Forgot to mention that I once asked a similar question https://stackoverflow.com/questions/6727255/aes-decryption-on-android-not-correct , the grammer problem there have been corrected.
And Here's the code:
For Encryption
public String AESEncrypt(String sKey, String PlainMsg)
throws Exception {
//Try use some Android based alert dialog to catch this exception.
if (sKey == null) {
Log.e("SecureChat", "IllegalArgumentException Catched");
throw new IllegalArgumentException ("NULL Secret NOT ALLOWED!");
}
/*Old Method
//byte[] rawKey = getRawKey(sKey.getBytes("UTF-8"));
byte[] rawKey = getRawKey(sKey.getBytes());
//Encrypt start
SecretKeySpec keySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, keySpec);
//byte[] cipherText = cipher.doFinal(PlainMsg.getBytes("UTF-8"));
byte[] cipherText = cipher.doFinal(PlainMsg.getBytes());
return Base64Encoded(cipherText);
*/
//New Method
byte[] salt = getSalt();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
KeySpec spec = new PBEKeySpec(sKey.toCharArray(), salt, 1024, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
//Encryption Process
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
byte[] cipherText = cipher.doFinal(PlainMsg.getBytes());
//return Base64Encoded(cipherText);
//Hex
return toHex(cipherText);
}
For Decryption
public String AESDecrypt(String sKey, String EncryptMsg)
throws Exception {
/*Old Method
//byte[] rawKey = getRawKey(sKey.getBytes("UTF-8"));
byte[] rawKey = getRawKey(sKey.getBytes());
SecretKeySpec keySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, keySpec);
//byte[] plainText = Base64Decoded(EncryptMsg.getBytes("UTF-8"));
byte[] plainText = Base64Decoded(EncryptMsg);
cipher.doFinal(plainText);
return new String(plainText, "UTF-8");
*/
//New Method
byte[] salt = getSalt();
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBEWITHSHA256AND256BITAES-CBC-BC");
KeySpec spec = new PBEKeySpec(sKey.toCharArray(), salt, 1024, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
//byte[] bCipherText = Base64Decoded(EncryptMsg);
//Hex
byte[] bCipherText = toByte(EncryptMsg);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
cipher.doFinal(bCipherText);
return new String(bCipherText);
}
private byte[] getSalt() throws NoSuchAlgorithmException {
/*Mark for old key method
//Initialize the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
//Init for 256bit AES key
kgen.init(Constants.AES_KEY_SIZE, sr);;
SecretKey secret = kgen.generateKey();
//Get secret raw key
byte[] rawKey = secret.getEncoded();
return rawKey;
*/
//New key method with some salt
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
byte[] ransalt = new byte[20];
random.nextBytes(ransalt);
return ransalt;
}
#Override
public byte[] getRawKey(byte[] seed) throws Exception {
/*Old Method
//Initialize the KeyGenerator
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
//Init for 256bit AES key
kgen.init(Constants.AES_KEY_SIZE, sr);
SecretKey secret = kgen.generateKey();
//Get secret raw key
byte[] rawKey = secret.getEncoded();
return rawKey;
*/
return null;
}
/**
*
* #param toBeDecoded
* #return
*/
public byte[] Base64Decoded(String toBeDecoded) {
byte[] decoded = Base64.decode(toBeDecoded, 0);
return decoded;
}
//Hex Mode
public String toHex(String txt) {
return toHex(txt.getBytes());
}
public String fromHex(String hex) {
return new String(toByte(hex));
}
public byte[] toByte(String hexString) {
int len = hexString.length()/2;
byte[] result = new byte[len];
for (int i = 0; i < len; i++)
result[i] = Integer.valueOf(hexString.substring(2*i, 2*i+2), 16).byteValue();
return result;
}
public String toHex(byte[] buf) {
if (buf == null)
return "";
StringBuffer result = new StringBuffer(2*buf.length);
for (int i = 0; i < buf.length; i++) {
appendHex(result, buf[i]);
}
return result.toString();
}
private final String HEX = "0123456789ABCDEF";
private void appendHex(StringBuffer sb, byte b) {
sb.append(HEX.charAt((b>>4)&0x0f)).append(HEX.charAt(b&0x0f));
}
}
I've referenced/compared with these code on Stackoverflow:
Android aes encryption pad block corrupted
and
incorrect decryption using AES/CBC/PKCS5Padding in Android
Seems that my problem lies on the charset encoding, but I cannot find out where the problem is.
Any comments/answers are very appreciated!
Thank you for helping me!
This code I wrote works flawlessly. Look at this link below:
http://pocket-for-android.1047292.n5.nabble.com/Encryption-method-and-reading-the-Dropbox-backup-td4344194.html#a4454327
Without looking too carefully at your code I would suggest you should specify the encoding here though I'm not sure if this is the cause of your problems:
byte[] cipherText = cipher.doFinal(PlainMsg.getBytes());
and here:
return new String(bCipherText);

Categories

Resources