I have done an encryption using the AES but iam not able to do the decryption Iam gettin an javax.crypto.IllegalBlockSizeException: last block incomplete in decryption.....I cant trace out where is the problem.I appreciate any help.
try {
in = new FileInputStream("/sdcard/Pic 1.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
File f=new File("/sdcard/Pic 1.txt");
buf = new byte[(int) f.length()+2];
try {
in.read(buf);
} catch (IOException e) {
e.printStackTrace();
}
try {
decryptedData = decrypt(key, buf);
decryptedimage = BitmapFactory.decodeByteArray(
decryptedData, 0, decryptedData.length);
loadedimage.setImageBitmap(decryptedimage);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void Encription(Bitmap bm) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
b = baos.toByteArray();
try {
keyStart = ".....".getBytes();
kgen = KeyGenerator.getInstance("AES");
sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(128, sr); // 192 and 256 bits may not be available
skey = kgen.generateKey();
key = skey.getEncoded();
encryptedData = encrypt(key, b);
encryptedimage = BitmapFactory.decodeByteArray(encryptedData, 0,
encryptedData.length);
out = new FileOutputStream("/sdcard/"+"Pic "+i+".txt");
out.write(encryptedData, 0, encryptedData.length);
out.close();
} catch (Exception e) {
}
i++;
}
private 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 byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
long start=System.currentTimeMillis()/1000l;
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
02-19 08:27:06.972: W/System.err(12742): javax.crypto.IllegalBlockSizeException: last block incomplete in decryption
Related
As files in android assets can be easily hacked by converting .apk to .zip. I have some propitiatory model which I need to use in android application. I am working on how to encrypt the assets of the application. ( I will use firebase for retreiving the key for decryption to make it more secure )
I am pretty successful in encrypting and decrypting images (png and jpg) using cipher library in android.
Following is the code which I used for the purpose.
String fake = "sadhkja6";
byte[] encodedKey = Base64.decode(fake, Base64.DEFAULT);
yourKey= new SecretKeySpec(encodedKey, 0, encodedKey.length, "AES");
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), id);
bitmap = Bitmap.createScaledBitmap(bitmap, 500,500, true);
byte[] output = getBytes(bitmap);
byte[] output = getBytesFile();
saveFile(output);
public static byte[] encodeFile(SecretKey yourKey, byte[] fileData)
throws Exception {
byte[] encrypted = null;
byte[] data = yourKey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(data, 0, data.length,
algorithm);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(
new byte[cipher.getBlockSize()]));
encrypted = cipher.doFinal(fileData);
return encrypted;
}
public byte[] getBytes(Bitmap bitmap){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress( Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
bitmap.recycle();
return byteArray;
}
public static byte[] encodeFile(SecretKey yourKey, byte[] fileData)
throws Exception {
byte[] encrypted = null;
byte[] data = yourKey.getEncoded();
SecretKeySpec skeySpec = new SecretKeySpec(data, 0, data.length,
algorithm);
Cipher cipher = Cipher.getInstance(algorithm);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(
new byte[cipher.getBlockSize()]));
encrypted = cipher.doFinal(fileData);
return encrypted;
}
void saveFile(byte[] array) {
String decrypted_file = "encypted.png";
try {
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator, decrypted_file);
BufferedOutputStream bos = new BufferedOutputStream(
new FileOutputStream(file));
yourKey = generateKey();
byte[] filesBytes = encodeFile(yourKey, array);
bos.write(filesBytes);
bos.flush();
bos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
But when I use the same code for encyrpting tensorflow models, the model is not successfully decompiled resulting in app crash. Most probably because we are loading the model in bytes which may cause problems.
Please tell me how can I use the cyphering technique for securing my tensorflow model. Thank you very much.
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.
I want to decrypt an encrypted String, but for small data it works well, for large String data it is showing some errors like:
java.lang.OutOfMemoryError
at java.io.ByteArrayOutputStream.expand(ByteArrayOutputStream.java:91)
at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:216)
at Decoder.BASE64Decoder.decodeAtom(BASE64Decoder.java:153)
at Decoder.CharacterDecoder.decodeBuffer(CharacterDecoder.java:178)
at Decoder.CharacterDecoder.decodeBuffer(CharacterDecoder.java:213)
This is my code snippet,
public static String Decrypt(String text, String key) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
byte[] keyBytes = new byte[16];
byte[] b = key.getBytes("UTF-8");
int len = b.length;
if (len > keyBytes.length)
len = keyBytes.length;
System.arraycopy(b, 0, keyBytes, 0, len);
SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
byte[] results = new byte[text.length()];
BASE64Decoder decoder = new BASE64Decoder();
try {
results = cipher.doFinal(decoder.decodeBuffer(text));
} catch (Exception e) {
Log.i("Erron in Decryption", e.toString());
}
return new String(results, "UTF-8");
}
Till kitkat, encryption/decryption is working good but in lollipop it decrypts only partial data.
I don't have problem with encryption because I encrypted a file with lollipop and decrypts it with kitkat it works fine but not vice versa.
Here is the code.
Encryption code
Encrypt(BufferedInputStream is, File destfile, String passcode) {
bis = is;
try {
fos = new FileOutputStream(destfile);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
dest = new BufferedOutputStream(fos, 1024);
this.passcode = passcode;
}
static void encrypt() throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec(passcode.getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[1024];
while ((b = bis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
bis.close();
}
Decryption code
public Decrypt(String path, String pathcode) {
// TODO Auto-generated constructor stub
filepath = path;
try {
fis = new FileInputStream(new File(path));
this.passcode = pathcode;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static String decrypt() throws IOException, NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException {
SecretKeySpec sks = new SecretKeySpec(passcode.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int size = fis.available();
byte[] resdata = new byte[size];
cis.read(resdata, 0, size);
String newres = new String(resdata, "UTF-8").trim();
//write("decrypted_file.xhtml",newres);
if(fis!=null)
{
fis.close();
}
if(cis!=null)
cis.close();
return newres;
}
What's the problem in this code? Do I need to do anything more?
available() doesn't necessarily return the length of the entire stream, just the estimated number of bytes that can be read without blocking. So, use a ByteArrayOutputStream to store the bytes and then covert to a byte array:
CipherInputStream cis = new CipherInputStream(fis, cipher);
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int bytesRead;
byte[] data = new byte[1024];
while ((bytesRead = cis.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, bytesRead);
}
buffer.flush();
byte[] resdata = buffer.toByteArray();
String newres = new String(resdata, "UTF-8").trim();
I've never worked with encryption before. Actually I know nothing about encryption. I have a file encrypted with openssl tool using params:
openssl aes-256-cbc -nosalt -in fileIn -out fileOUT -p -k KEY
I need to decrypt it into memory but I don't know how. Can anyone provide me the code related to encryption?
Here's class I have written to decrypt a string encoded with params above (if I remmeber it correct):
public class CipherUtils {
public static byte[] getKey(String password, byte[] salt) {
try {
byte[] passwordSalt = EncodingUtils.getAsciiBytes(password);
passwordSalt = concatenateByteArrays(passwordSalt, salt);
byte[] hash1 = getHashForHash(null, passwordSalt);
byte[] hash2 = getHashForHash(hash1, passwordSalt);
byte[] key = concatenateByteArrays(hash1, hash2);
return key;
} catch (Exception e) {
return null;
}
}
public static byte[] getIV(String password, byte[] salt) {
try {
byte[] passwordSalt = EncodingUtils.getAsciiBytes(password);
passwordSalt = concatenateByteArrays(passwordSalt, salt);
byte[] hash1 = getHashForHash(null, passwordSalt);
byte[] hash2 = getHashForHash(hash1, passwordSalt);
byte[] hash3 = getHashForHash(hash2, passwordSalt);
return hash3;
} catch (Exception e) {
return null;
}
}
private static byte[] getHashForHash(byte[] hash, byte[] passwordSalt) {
try {
byte[] hashMaterial = concatenateByteArrays(hash, passwordSalt);
MessageDigest md = MessageDigest.getInstance("MD5");
return md.digest(hashMaterial);
} catch (Exception e) {
return null;
}
}
private static byte[] concatenateByteArrays(byte[] a, byte[] b) {
if (a == null)
return b;
if (b == null)
return a;
byte[] result = new byte[a.length + b.length];
System.arraycopy(a, 0, result, 0, a.length);
System.arraycopy(b, 0, result, a.length, b.length);
return result;
}
}
Salt is an empty bytearray in this case. It uses apache-commons-compress.jar.
Here's usage example:
byte[] key = CipherUtils.getKey(password, null);
byte[] IV = CipherUtils.getIV(password, null);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "AES"),
new IvParameterSpec(IV));
cis = new CipherInputStream(is, cipher);
Where is is an InputStream of encrypted data.
this may helps you
public void encrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
// Here you read the cleartext.
FileInputStream fis = new FileInputStream("data/cleartext");
// This stream write the encrypted text. This stream will be wrapped by
// another stream.
FileOutputStream fos = new FileOutputStream("data/encrypted");
// Length is 16 byte
SecretKeySpec sks = new SecretKeySpec("yourkey".getBytes(), "AES");
// Create cipher
Cipher cipher = Cipher.getInstance("AES/CBC");
cipher.init(Cipher.ENCRYPT_MODE, sks);
// Wrap the output stream
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
// Write bytes
int b;
byte[] d = new byte[8];
while ((b = fis.read(d)) != -1) {
cos.write(d, 0, b);
}
// Flush and close streams.
cos.flush();
cos.close();
fis.close();
}
Decrypt
public void decrypt() throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
FileInputStream fis = new FileInputStream("data/encrypted");
FileOutputStream fos = new FileOutputStream("data/decrypted");
SecretKeySpec sks = new SecretKeySpec("yourkey".getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC");
cipher.init(Cipher.DECRYPT_MODE, sks);
CipherInputStream cis = new CipherInputStream(fis, cipher);
int b;
byte[] d = new byte[8];
while((b = cis.read(d)) != -1) {
fos.write(d, 0, b);
}
fos.flush();
fos.close();
cis.close();
}