Encrypting a message using a key - android

I need to encrypt a message using a key in Android.
How can I convert the below code to work with Android
public static String EncryptData(byte[] key, byte[] msg)
throws Exception {
String encryptedData = "";
AESKey key = new AESKey(keyData);
NoCopyByteArrayOutputStream out = new NoCopyByteArrayOutputStream();
AESEncryptorEngine engine = new AESEncryptorEngine(key);
BlockEncryptor encryptor = new BlockEncryptor(engine, out);
encryptor.write(data, 0, data.length);
int finalLength = out.size();
byte[] cbytes = new byte[finalLength];
System.arraycopy(out.getByteArray(), 0, cbytes, 0, finalLength);
encryptedData = getHexString(cbytes);
return encryptedData;
}

as this is java code for encryption you can use this code as it is in your class . this is AES algorithm encryption so you just need to create methods for encryption and decryption
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws
Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
... for reference you can follow the example given-
Aes encryption example

Related

Error: bad base-64 when decrypting a string Java

I'm attempting to encrypt and encrypt strings (passwords). I'm trying to encrypt I've tried all Base64 encoding options and it continues to return bad base-64.
private String encrypt(String password) throws Exception {
SecretKeySpec key = generatePasswordKey(databaseSetup.getAES());
#SuppressLint("GetInstance") Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, key);
byte[] encodeBytes = c.doFinal(password.getBytes());
return Base64.encodeToString(encodeBytes, Base64.NO_WRAP);
}
private String decrypt(String password) throws Exception {
SecretKeySpec key = generatePasswordKey(databaseSetup.getAES());
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, key);
byte[] decodedBytes = Base64.decode(password, Base64.NO_WRAP);
byte[] decryptedVal = c.doFinal(decodedBytes);
String decryptedPassword = new String(decryptedVal);
return decryptedPassword;
}
private SecretKeySpec generatePasswordKey(String password) throws NoSuchAlgorithmException {
final MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
byte[] bytes = password.getBytes();
messageDigest.update(bytes, 0, bytes.length);
byte[] key = messageDigest.digest();
return new SecretKeySpec(key, "AES");
}

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

FBEncrypter library compatibility with Android

I have already use below library for encryption and decryption in iOS.
https://github.com/dev5tec/FBEncryptor
Now I want same functionality in Android. Is there any support for Android also? If not then how can I use this library to fulfil my need in Android also or please suggest another other encryption library that work same as FBEncryptor.
I have implemented the following code.
public class AESHelper {
private final Cipher cipher;
private final SecretKeySpec key;
private AlgorithmParameterSpec spec;
private static final String KEY = "VHJFTFRGJHGHJDhkhjhd/dhfdh=";
public AESHelper() throws Exception {
byte[] keyBytes = KEY.getBytes("UTF-8");
Arrays.fill(keyBytes, (byte) 0x00);
cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
key = new SecretKeySpec(keyBytes, "AES");
spec = getIV();
}
public AlgorithmParameterSpec getIV() {
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
return new IvParameterSpec(iv);
}
public String encrypt(String plainText) throws Exception {
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
String encryptedText = new String(Base64.encode(encrypted, Base64.DEFAULT), "UTF-8");
return encryptedText;
}
public String decrypt(String cryptedText) throws Exception {
cipher.init(Cipher.DECRYPT_MODE, key, spec);
byte[] bytes = Base64.decode(cryptedText, Base64.DEFAULT);
byte[] decrypted = cipher.doFinal(bytes);
String decryptedText = new String(decrypted, "UTF-8");
return decryptedText;
}
}
But it throw javax.crypto.BadPaddingException: Pad Block Corrupted
finally i have found solution for my own question.
For encryption in android you can use https://gist.github.com/m1entus/f70d4d1465b90d9ee024.
This class work same as like https://github.com/dev5tec/FBEncryptor in ios.

Bad pad corrupt error in ANDROID encrypted in Java project

I am ecrypting the data in java(Java project using AES) and want to decrypt the data in android but I am getting bad pad corrupt error.If same is run on java project its woking.Java project and android code is below:
Java Side code(Java Project):
enter code here
public static void main(String[] args) {
//Same password used in android
String masterpassword ="test";
String crypto = encrypt(masterpassword, "XYZ");
}
public static String encrypt(String seed, String cleartext) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
System.out.println(rawKey);
byte[] result = encrypt(rawKey, cleartext.getBytes());
return Base64.encode(result);
// return toHex(result);
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
Android Side Code:
*
public void onDecrypt(View view){
System.out.println("onDecrypt ");
String param = "w7ayjByx5I0yrX2tT8gj4w==";//Encrypted data
String masterpassword ="test";
try {
String res = decrypt(masterpassword, param);
}
}
*
public static String decrypt(String seed, String encrypted) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes());
System.out.println(rawKey);
// byte[] enc = toByte(encrypted);
byte[] enc = Base64.decode(encrypted);
byte[] result = decrypt(rawKey, enc);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
Pls help.
Here is one mistake. In these lines ...
Java (encrypt side)
byte[] result = encrypt(rawKey, cleartext.getBytes());
Android(decrypt side):
return new String(result);
... you are using the default platform character set encoding. Never do that, always explicitly specify the charset encoding. Just use "UTF-8" which is universal and, except perhaps for some Asian languages, optimally space efficient. So, use the correct getBytes() method and String constructor.
I also notice you are using a SecureRandom instance to expand a seed. This is a pretty non-standard way of doing this. It might work but it is a bad idea.

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