Category Archives: Encrypt

How to encrypt and decrypt a file using “AES” algorithm in Android? – Google’s Advice

This is a simple example showing how to encrypt and decrypt a file in android.
what we will do in this post is

1. Generate a key for encrypting our data.
2. Create a file and save data using ENCRYPTION with our generated key to the SDCARD.
3. With the help of the key DECRYPT the File and show the contents.

An anti-pattern
A common (but incorrect) pattern that we’ve recently become aware of is to use SecureRandom as a means of generating deterministic key material, which would then be used to encrypt local credential caches. Examples are not hard to find, such as here, here, here, and elsewhere.

In this pattern, rather than storing an encryption key directly as a string inside an APK, the code uses a proxy string to generate the key instead — similar to a passphrase. This essentially obfuscates the key so that it’s not readily visible to attackers. However, a skilled attacker would be able to easily see around this strategy. We don’t recommend it.

This complete program does this.
Please check the Logcat for the output.

package com.coderzheaven.encryptfile;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;

public class MainActivity extends Activity {

	private String encryptedFileName = "Enc_File.txt";
	private static String algorithm = "AES";
	static SecretKey yourKey = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		saveFile("Hello From CoderzHeaven asaksjalksjals");
		decodeFile();

	}
	
	public static SecretKey generateKey(char[] passphraseOrPin, byte[] salt) throws NoSuchAlgorithmException, InvalidKeySpecException {
	    // Number of PBKDF2 hardening rounds to use. Larger values increase
	    // computation time. You should select a value that causes computation
	    // to take >100ms.
	    final int iterations = 1000; 

	    // Generate a 256-bit key
	    final int outputKeyLength = 256;

	    SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
	    KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations, outputKeyLength);
	    SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
	    return secretKey;
	}

	public static SecretKey generateKey() throws NoSuchAlgorithmException {
		// Generate a 256-bit key
		final int outputKeyLength = 256;
		SecureRandom secureRandom = new SecureRandom();
		// Do *not* seed secureRandom! Automatically seeded from system entropy.
		KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
		keyGenerator.init(outputKeyLength, secureRandom);
		yourKey = keyGenerator.generateKey();
		return yourKey;
	}

	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 static byte[] decodeFile(SecretKey yourKey, byte[] fileData)
			throws Exception {
		byte[] decrypted = null;
		Cipher cipher = Cipher.getInstance(algorithm);
		cipher.init(Cipher.DECRYPT_MODE, yourKey, new IvParameterSpec(
				new byte[cipher.getBlockSize()]));
		decrypted = cipher.doFinal(fileData);
		return decrypted;
	}

	void saveFile(String stringToSave) {
		try {
			File file = new File(Environment.getExternalStorageDirectory()
					+ File.separator, encryptedFileName);
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream(file));
			yourKey = generateKey();
			byte[] filesBytes = encodeFile(yourKey, stringToSave.getBytes());
			bos.write(filesBytes);
			bos.flush();
			bos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	void decodeFile() {

		try {
			byte[] decodedData = decodeFile(yourKey, readFile());
			String str = new String(decodedData);
			System.out.println("DECODED FILE CONTENTS : " + str);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public byte[] readFile() {
		byte[] contents = null;

		File file = new File(Environment.getExternalStorageDirectory()
				+ File.separator, encryptedFileName);
		int size = (int) file.length();
		contents = new byte[size];
		try {
			BufferedInputStream buf = new BufferedInputStream(
					new FileInputStream(file));
			try {
				buf.read(contents);
				buf.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return contents;
	}

}


IF YOU WANT MORE SUCURITY THEN USE THE BELOW CODE…

If your app needs additional encryption, a recommended approach is to require a passphase or PIN to access your application. This passphrase could be fed into PBKDF2 to generate the encryption key. (PBKDF2 is a commonly used algorithm for deriving key material from a passphrase, using a technique known as “key stretching”.) Android provides an implementation of this algorithm inside SecretKeyFactory as PBKDF2WithHmacSHA1:

package com.coderzheaven.encryptfile;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import android.app.Activity;
import android.os.Bundle;
import android.os.Environment;

public class ActivityEncrypt extends Activity {

	private String encryptedFileName = "Enc_File2.txt";
	private static String algorithm = "AES";
	static SecretKey yourKey = null;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);

		saveFile("Hello From CoderzHeaven testing ");
		decodeFile();

	}

	public static SecretKey generateKey(char[] passphraseOrPin, byte[] salt)
			throws NoSuchAlgorithmException, InvalidKeySpecException {
		// Number of PBKDF2 hardening rounds to use. Larger values increase
		// computation time. You should select a value that causes computation
		// to take >100ms.
		final int iterations = 1000;

		// Generate a 256-bit key
		final int outputKeyLength = 256;

		SecretKeyFactory secretKeyFactory = SecretKeyFactory
				.getInstance("PBKDF2WithHmacSHA1");
		KeySpec keySpec = new PBEKeySpec(passphraseOrPin, salt, iterations,
				outputKeyLength);
		yourKey = secretKeyFactory.generateSecret(keySpec);
		return yourKey;
	}

	public static SecretKey generateSalt() throws NoSuchAlgorithmException {
		// Generate a 256-bit key
		final int outputKeyLength = 256;

		SecureRandom secureRandom = new SecureRandom();
		// Do *not* seed secureRandom! Automatically seeded from system entropy.
		KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
		keyGenerator.init(outputKeyLength, secureRandom);
		SecretKey key = keyGenerator.generateKey();
		return key;
	}

	public static byte[] encodeFile(SecretKey yourKey, byte[] fileData)
			throws Exception {
		byte[] data = yourKey.getEncoded();
		SecretKeySpec skeySpec = new SecretKeySpec(data, 0, data.length,
				algorithm);
		Cipher cipher = Cipher.getInstance(algorithm);
		cipher.init(Cipher.ENCRYPT_MODE, skeySpec);

		byte[] encrypted = cipher.doFinal(fileData);

		return encrypted;
	}

	public static byte[] decodeFile(SecretKey yourKey, byte[] fileData)
			throws Exception {
		byte[] data = yourKey.getEncoded();
		SecretKeySpec skeySpec = new SecretKeySpec(data, 0, data.length,
				algorithm);
		Cipher cipher = Cipher.getInstance(algorithm);
		cipher.init(Cipher.DECRYPT_MODE, skeySpec);

		byte[] decrypted = cipher.doFinal(fileData);

		return decrypted;
	}

	void saveFile(String stringToSave) {
		try {
			File file = new File(Environment.getExternalStorageDirectory()
					+ File.separator, encryptedFileName);
			BufferedOutputStream bos = new BufferedOutputStream(
					new FileOutputStream(file));
			char[] p = { 'p', 'a', 's', 's' };
			SecretKey yourKey = generateKey(p, generateSalt().toString()
					.getBytes());
			byte[] filesBytes = encodeFile(yourKey, stringToSave.getBytes());
			bos.write(filesBytes);
			bos.flush();
			bos.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	void decodeFile() {
		try {
			byte[] decodedData = decodeFile(yourKey, readFile());
			String str = new String(decodedData);
			System.out.println("DECODED FILE CONTENTS : " + str);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public byte[] readFile() {
		byte[] contents = null;

		File file = new File(Environment.getExternalStorageDirectory()
				+ File.separator, encryptedFileName);
		int size = (int) file.length();
		contents = new byte[size];
		try {
			BufferedInputStream buf = new BufferedInputStream(
					new FileInputStream(file));
			try {
				buf.read(contents);
				buf.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return contents;
	}

}

Useful information collected from this link.
http://android-developers.blogspot.in/2013/02/using-cryptography-to-store-credentials.html

How to encrypt a string in Android Using Base64?

package com.coderzheaven.encryptstring;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Base64;

@SuppressLint({ "WorldReadableFiles", "WorldWriteableFiles" })
public class MainActivity extends Activity {

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		saveText("CoderzHeaven");
		System.out.println(getText());
	}

	public void saveText(String text) {
		SharedPreferences myPrefs = this.getSharedPreferences("myPrefs",
				MODE_WORLD_READABLE);
		SharedPreferences.Editor editor = myPrefs.edit();
		text = Base64.encodeToString(text.getBytes(), Base64.DEFAULT);
		editor.putString("some_text", text);
		editor.commit();
	}

	public String getText() {
		SharedPreferences myPrefs = this.getSharedPreferences("myPrefs",
				MODE_WORLD_WRITEABLE);
		String text = myPrefs.getString("some_text", null);
		text = new String(Base64.decode(text, Base64.DEFAULT));
		return text;
	}
}

Please check the LogCat for output.

Join the Forum discussion on this post