Android Passing IV parameters Encryption /Decryption text - android

I Hope that you can help me related my code.
Im trying to pass parameters IV to Encrypt/ Decryt
Encrypt Funcion:
I try to concatenate text; IV
encryptedText.setText(Base64.encodeToString(vals, Base64.DEFAULT) + ";" + (Base64.encodeToString(encryptionIv, Base64.DEFAULT)));
I think that is working fine , as the image represents.
public void encryptString(String alias) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey secretKey = (SecretKey) keyStore.getKey(alias, null);
String initialText = startText.getText().toString();
if(initialText.isEmpty()) {
Toast.makeText(this, "Enter text in the 'Initial Text'", Toast.LENGTH_LONG).show();
return;
}
Cipher inCipher = Cipher.getInstance("AES/GCM/NoPadding");
inCipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] src= initialText.getBytes("UTF-8");
byte[] iv = inCipher.getIV();
assert iv.length == 12;
byte[] cipherText = inCipher.doFinal(src);
assert cipherText.length == src.length + 16;
byte[] message = new byte[12 + src.length + 16];
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, inCipher);
cipherOutputStream.write(src);
cipherOutputStream.close();
byte [] vals = outputStream.toByteArray();
encryptedText.setText(Base64.encodeToString(vals, Base64.DEFAULT));
} catch (Exception e) {
Toast.makeText(this, "Exception " + e.getMessage() + " occurred", Toast.LENGTH_LONG).show();
Log.e(TAG, Log.getStackTraceString(e));
}
}
[![enter image description here][1]][1]
Could you helpme with an example to get decryption works fine?
Thanks for youl help
Updated: Hello , Im trying to pass the IV as the example:
My code here:
public void encryptString(String alias) {
try {
KeyStore.PrivateKeyEntry privateKeyEntry = (KeyStore.PrivateKeyEntry)keyStore.getEntry(alias, null);
RSAPublicKey publicKey = (RSAPublicKey) privateKeyEntry.getCertificate().getPublicKey();
String initialText = startText.getText().toString();
if(initialText.isEmpty()) {
Toast.makeText(this, "Enter text in the 'Initial Text' widget", Toast.LENGTH_LONG).show();
return;
}
Cipher inCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "AndroidOpenSSL");
inCipher.init(Cipher.ENCRYPT_MODE, publicKey);
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
CipherOutputStream cipherOutputStream = new CipherOutputStream(
outputStream, inCipher);
cipherOutputStream.write(initialText.getBytes("UTF-8"));
cipherOutputStream.close();
byte [] vals = outputStream.toByteArray();
encryptedText.setText(Base64.encodeToString(vals, Base64.DEFAULT));
} catch (Exception e) {
Toast.makeText(this, "Exception " + e.getMessage() + " occurred", Toast.LENGTH_LONG).show();
Log.e(TAG, Log.getStackTraceString(e));
}
}
[![enter image description here][2]][2]
NEW Updated:
Encryption code
public void encryptString(String alias) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey secretKey = (SecretKey) keyStore.getKey(alias, null);
String initialText = startText.getText().toString();
if(initialText.isEmpty()) {
Toast.makeText(this, "Enter text in the 'Initial Text'", Toast.LENGTH_LONG).show();
return;
}
Cipher inCipher = Cipher.getInstance("AES/GCM/NoPadding");
inCipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] src= initialText.getBytes("UTF-8");
byte[] iv = inCipher.getIV();
assert iv.length == 12;
byte[] cipherText = inCipher.doFinal(src);
assert cipherText.length == src.length + 16;
byte[] message = new byte[12 + src.length + 16];
System.arraycopy(iv, 0, message, 0, 12);
System.arraycopy(cipherText, 0, message, 12, cipherText.length);
//ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
//CipherOutputStream cipherOutputStream = new CipherOutputStream(
// outputStream, inCipher);
//cipherOutputStream.write(message);
//cipherOutputStream.close();
//byte [] vals = outputStream.toByteArray();
encryptedText.setText(Base64.encodeToString(message, Base64.DEFAULT));
} catch (Exception e) {
Toast.makeText(this, "Exception " + e.getMessage() + " occurred", Toast.LENGTH_LONG).show();
Log.e(TAG, Log.getStackTraceString(e));
}
}
Decryption code: ( Not working)
public void decryptString(String alias) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey secretKey = (SecretKey) keyStore.getKey(alias, null);
String cipherText = encryptedText.getText().toString();
byte[] src = cipherText.getBytes();
byte[] message = new byte[12 + src.length + 16];
Cipher output = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec params = new GCMParameterSpec(128, message, 0, 12);
output.init(Cipher.DECRYPT_MODE, secretKey, params);
// output.doFinal(message, 12, message.length - 12);
CipherInputStream cipherInputStream = new CipherInputStream(
new ByteArrayInputStream(Base64.decode(cipherText, Base64.DEFAULT)), output);
ArrayList<Byte> values = new ArrayList<>();
int nextByte;
while ((nextByte = cipherInputStream.read()) != -1) {
values.add((byte)nextByte);
}
byte[] bytes = new byte[values.size()];
for(int i = 0; i < bytes.length; i++) {
bytes[i] = values.get(i).byteValue();
}
String finalText = new String(bytes, 0, bytes.length, "UTF-8");
decryptedText.setText(finalText);
} catch (Exception e) {
Toast.makeText(this, "Exception " + e.getMessage() + " occurred", Toast.LENGTH_LONG).show();
Log.e(TAG, Log.getStackTraceString(e));
}
}
Could you help me with the error shows in the image?
[![enter image description here][3]][3]
<<---UPDATED SOLUTION-->
Encript function:
public void encryptString(String alias) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey secretKey = (SecretKey) keyStore.getKey(alias, null);
String initialText = startText.getText().toString();
if(initialText.isEmpty()) {
Toast.makeText(this, "Enter text in the 'Initial Text'", Toast.LENGTH_LONG).show();
return;
}
Cipher inCipher = Cipher.getInstance("AES/GCM/NoPadding");
inCipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] src= initialText.getBytes("UTF-8");
byte[] iv = inCipher.getIV();
assert iv.length == 12;
byte[] cipherText = inCipher.doFinal(src);
assert cipherText.length == src.length + 16;
byte[] message = new byte[12 + src.length + 16];
System.arraycopy(iv, 0, message, 0, 12);
System.arraycopy(cipherText, 0, message, 12, cipherText.length);
encryptedText.setText(Base64.encodeToString(message, Base64.DEFAULT));
} catch (Exception e) {
Toast.makeText(this, "Exception " + e.getMessage() + " occurred", Toast.LENGTH_LONG).show();
Log.e(TAG, Log.getStackTraceString(e));
}
}
Decrypt Function:
public void decryptString(String alias) {
try {
KeyStore keyStore = KeyStore.getInstance("AndroidKeyStore");
keyStore.load(null);
SecretKey secretKey = (SecretKey) keyStore.getKey(alias, null);
String cipherText = encryptedText.getText().toString();
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
byte[] nonceCiphertextTag = Base64.decode(cipherText, Base64.DEFAULT);
GCMParameterSpec params = new GCMParameterSpec(128, nonceCiphertextTag, 0, 12);
cipher.init(Cipher.DECRYPT_MODE, secretKey, params);
byte[] decrypted = cipher.doFinal(nonceCiphertextTag, 12, nonceCiphertextTag.length - 12);
String finalText = new String(decrypted, 0, decrypted.length, "UTF-8");
decryptedText.setText(finalText);
} catch (Exception e) {
Toast.makeText(this, "Exception " + e.getMessage() + " occurred", Toast.LENGTH_LONG).show();
Log.e(TAG, Log.getStackTraceString(e));
}
}
Thanks a lot for the help #Topaco

In the latest posted encryption code, nonce, ciphertext and tag are concatenated and Base64 encoded, in the following called nonceCiphertextTagB64.
When decrypting
nonceCiphertextTagB64 must first be Base64 decoded to nonceCiphertextTag,
the nonce must be encapsulated in a GCMParameterSpec instance; the nonce are the first 12 bytes of nonceCiphertextTag,
a cipher instance for AES/GCM/NoPadding must be created, which is initialized with the key and the GCMParameterSpec instance in decryption mode,
the concatenation of ciphertext and tag is decrypted; the concatenation of ciphertext and tag is the data after the nonce.
In the following example implementation, with respect to a repro, the 32 bytes key 01234567890123456789012345678901 is used (instead of a key from the key store). The ciphertext was created with the posted code for encryption using the same key and the plaintext The quick brown fox jumps over the lazy dog:
...
String nonceCiphertextTagB64 =
"UpyxMnzPrw+zJGANL4wBbaC+UX5KnMKYwhR0u2iF/GDCcU38YKWlvJp1zJ+mrN0POP7lz9y+eweH\n" +
"vIxAH4R4U3At8T0fVe0=";
SecretKeySpec secretKey = new SecretKeySpec("01234567890123456789012345678901".getBytes(StandardCharsets.UTF_8),"AES");
byte[] nonceCiphertextTag = Base64.decode(nonceCiphertextTagB64, Base64.DEFAULT);
GCMParameterSpec params = new GCMParameterSpec(128, nonceCiphertextTag, 0, 12);
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, params);
byte[] decrypted = cipher.doFinal(nonceCiphertextTag, 12, nonceCiphertextTag.length - 12);
System.out.println(new String(decrypted, StandardCharsets.UTF_8)); // The quick brown fox jumps over the lazy dog
...
The output is:
The quick brown fox jumps over the lazy dog

Related

android AES decrypt files: BadPaddingException: EVP_CipherFinal_ex

I am recently working on file encryption / decryption.
BadPaddingException: EVP_CipherFinal_ex: always occurs when I try to decrypt the file with the same key.
Code snippets will be posted below.
Am I doing something wrong?
thank you for your helps.
Encrypt
public static void encryptFile() {
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + TARGET_FILE);
FileInputStream fileInputStream;
FileOutputStream fileOutputStream;
byte[] buffer = new byte[1024 * 8];
IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567890123456".getBytes());
byte[] key = "only for testing".getBytes();
MessageDigest sha;
try {
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
key = Arrays.copyOf(key, 16); // use only first 128 bit
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
try {
fileInputStream = new FileInputStream(file);
fileOutputStream = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/" + ENCRYPT_FILE);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
//CipherOutputStream cipherOutputStream = new CipherOutputStream(fileOutputStream, cipher);
int read;
while ((read = fileInputStream.read(buffer)) > 0) {
Log.i(TAG, "encrypt read= " + read);
byte[] encryptedData = cipher.doFinal(buffer);
if (encryptedData != null) {
Log.i(TAG, "encrypted size= " + encryptedData.length);
fileOutputStream.write(encryptedData, 0, read);
}
//cipherOutputStream.write(buffer, 0, buffer.length);
}
//cipherOutputStream.flush();
//cipherOutputStream.close();
fileInputStream.close();
fileOutputStream.close();
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException
| IllegalBlockSizeException | BadPaddingException
| InvalidAlgorithmParameterException | InvalidKeyException e) {
e.printStackTrace();
}
}
Decrypt
public static void decryptFile() {
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/" + ENCRYPT_FILE);
FileInputStream fileInputStream;
FileOutputStream fileOutputStream;
byte[] buffer = new byte[1024 * 8];
IvParameterSpec ivParameterSpec = new IvParameterSpec("1234567890123456".getBytes());
byte[] key = "only for testing".getBytes();
MessageDigest sha;
try {
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
key = Arrays.copyOf(key, 16); // use only first 128 bit
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
try {
fileInputStream = new FileInputStream(file);
fileOutputStream = new FileOutputStream(Environment.getExternalStorageDirectory().getPath() + "/" + DECRYPT_FILE);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
//CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher);
int read;
while ((read = fileInputStream.read(buffer)) > 0) {
Log.i(TAG, "decrypt read= " + read);
byte[] decryptedData = cipher.doFinal(buffer);
if (decryptedData != null) {
Log.i(TAG, "decrypted size= " + decryptedData.length);
fileOutputStream.write(decryptedData, 0, read);
}
//fileOutputStream.write(buffer, 0, buffer.length);
}
fileOutputStream.flush();
fileOutputStream.close();
//cipherInputStream.close();
fileInputStream.close();
} catch (IOException | NoSuchAlgorithmException | NoSuchPaddingException
| IllegalBlockSizeException | BadPaddingException
| InvalidAlgorithmParameterException | InvalidKeyException e) {
e.printStackTrace();
}
}
btw: It will work properly when I use CipherInputStream / CipherOutStream. I want to know if it is possible to use just FileInputStream / FileOutputStream only? thank you.
Edited:
Encrypt function will enlarge byte array about 16 bytes, I've tried increase the buffer size of decryption and still can't get it work.
byte[] buffer = new byte[1024 * 8 + 16];
Log:
I/#_: decrypt read= 8208
javax.crypto.BadPaddingException: EVP_CipherFinal_ex
at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
at com.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430)
at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:466)
at javax.crypto.Cipher.doFinal(Cipher.java:1340)
at CryptoHelper.decryptFile(CryptoHelper.java:128)
Edited Update code here based on #Robert's answer for anyone who encountered the same problems like I did.
Encrypt:
int read;
while ((read = fileInputStream.read(buffer)) > 0) {
Log.i(TAG, "encrypt read= " + read);
byte[] encryptedData = cipher.update(buffer, 0, read);
//byte[] encryptedData = cipher.doFinal(buffer);
if (encryptedData != null) {
Log.i(TAG, "encrypted size= " + encryptedData.length);
fileOutputStream.write(encryptedData, 0, encryptedData.length);
}
//cipherOutputStream.write(buffer, 0, buffer.length);
}
byte[] finals = cipher.doFinal();
Log.i(TAG, "encrypted finals = " + finals.length);
fileOutputStream.write(finals, 0, finals.length);
Decrypt:
int read;
while ((read = fileInputStream.read(buffer)) > 0) {
Log.i(TAG, "decrypt read= " + read);
//byte[] decryptedData = cipher.doFinal(buffer);
byte[] decryptedData = cipher.update(buffer, 0, read);
if (decryptedData != null) {
Log.i(TAG, "decrypted size= " + decryptedData.length);
fileOutputStream.write(decryptedData, 0, decryptedData.length);
}
//fileOutputStream.write(buffer, 0, buffer.length);
}
byte[] finals = cipher.doFinal();
Log.i(TAG, "decrypted finals = " + finals.length);
fileOutputStream.write(finals, 0, finals.length);
Thanks again for Robert's help.
You problem is that you are always calling cipher.doFinal() for each block of data which is wrong as each block will be padded.
If you are en/decrypting data block-wise use cipher.update(...) and after the last block has been processed only call cipher.doFinal() once.
The easier way would be to use a CipherInputStream/CipherOutputStream - it does exactly what I have described for you (doFinal is called when you close the stream).

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;
}
}

Android AES encryption and decryption

I have found hundreds of examples of Android AES encryption and decryption but I am unable to make them work, even the simplest. The following code does some encryption and decryption but it spits out garbage after decrypting the encrypted text. Can you please take a look and tell me where I am wrong?
Thanks
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128, new SecureRandom());
SecretKey secretKey = keyGenerator.generateKey();
Cipher cipher = Cipher.getInstance("AES");
String plainText = "This is supposed to be encrypted";
String plainKey = Base64.encodeToString(secretKey.getEncoded(), Base64.DEFAULT);
//encrypt
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());
String encryptedText = Base64.encodeToString(encryptedBytes, Base64.DEFAULT);
//decrypt
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[]decryptedBytes = cipher.doFinal(encryptedBytes);
String decryptedText = Base64.encodeToString(decryptedBytes, Base64.DEFAULT);
#Barend answer works:
Your code works fine. What #greenapps said. Instead of Base64.encodeToString(..), try printing the output of new String(decryptedBytes), you'll see that it's the value you were looking for.
SecretKeySpec sks = null;
try {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed("Complex Key for encryption".getBytes());
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128, sr);
sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");
} catch (Exception e) {
Log.e(TAG, "AES secret key spec error");
}
// Encode the original data with AES
byte[] encodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, sks);
encodedBytes = c.doFinal(theTestText.getBytes());
} catch (Exception e) {
Log.e(TAG, "AES encryption error");
}
TextView tvencoded = (TextView)findViewById(R.id.textitem2);
tvencoded.setText("[ENCODED]:\n" +
Base64.encodeToString(encodedBytes, Base64.DEFAULT) + "\n");
// Decode the encoded data with AES
byte[] decodedBytes = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.DECRYPT_MODE, sks);
decodedBytes = c.doFinal(encodedBytes);
} catch (Exception e) {
Log.e(TAG, "AES decryption error");
}
TextView tvdecoded = (TextView)findViewById(R.id.textitem3);
tvdecoded.setText("[DECODED]:\n" + new String(decodedBytes) + "\n");

Cipher AES, no error exception, but init not works

i try to cipher but my outputs after "cipher.init" won't output. Also no exceptions..and I don't know why...(new on android)
public void login() {
LoginData loginData = this.fragmentBox.getUpdatedLoginData();
String finishString = new String();
try {
Cipher cipher = Cipher.getInstance("AES");
byte[] output = null;
SecretKeySpec secretKey = new SecretKeySpec(
Globals.ENCRYPTPW.getBytes(), "AES");
System.out.println(secretKey.getEncoded().toString() + "----" + Globals.ENCRYPTPW);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
output = cipher.doFinal(loginData.getPassword().getBytes());
byte[] encryptedUsernameString = Base64.encode(output, 0);
finishString = new String(encryptedUsernameString, "UTF-8");
} catch (InvalidKeyException e) {
e.getStackTrace();
Log.v("Fehler im Code","");
} catch(Exception e){}
System.out.println("Code: " + finishString);
}
any idea?

AES Padding issue Android

When I run the following code in Java the output is a multiple of 128 bits (16 bytes).
The exact same code in Android is no longer a multiple of 16 bytes suggesting that the padding has failed.
Any ideas?
//Compress, Encrypt, Decrypt, Decompress variables
public final static String Secretkey = "###hidden######";
public final static String VectorInitializationKey = "###hidden###";
public final static String transformation = "AES/CFB8/PKCS5Padding";
public static byte[] encryptandCompress(byte[] input)
{
ByteArrayOutputStream ms = new ByteArrayOutputStream();
GZIPOutputStream gos = null; // Added
CipherOutputStream cos= null; // Added
SecretKeySpec skeySpec = new SecretKeySpec(Secretkey.getBytes(), "AES");
Cipher cipher;
try {
cipher = Cipher.getInstance(transformation);
IvParameterSpec iv = new IvParameterSpec(VectorInitializationKey.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
cos = new CipherOutputStream(ms, cipher );
gos= new GZIPOutputStream (cos);
gos.write(input);
gos.close(); // Must be called before we return bytes from ms
cos.close();
byte[] toReturn = ms.toByteArray();
Log.d("FileWriter", "Encrypted and compressed " + input.length + " bytes to " + toReturn.length + " bytes");
Log.d("FileWriter", "Encrypted and compressed " + toReturn.length/16.0 + " blocks written");
return toReturn;
} catch (Exception e) {
Log.e("FileWriter", "Compression failed: " + e.getMessage());
return null;
}
finally
{
try
{
if (gos != null)
{
gos.close();
}
if (cos != null)
{
cos.close();
}
if (ms != null)
{
ms.close();
}
}
catch (IOException e) {
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}

Categories

Resources