How do I decrypt message encrypt in here? - java

try{
String plainData="my name is laksahan",cipherText,decryptedText;
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey secretKey = keyGen.generateKey();
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);
byte[] byteDataToEncrypt = plainData.getBytes();
byte[] byteCipherText = aesCipher.doFinal(byteDataToEncrypt);
cipherText = new BASE64Encoder().encode(byteCipherText);
System.out.println(cipherText);
}catch(Exception e){
}
I also have the decrypting code, but I want to decrypt the message using the output of cipherText.
eg; my ciphertext output is uSG1OxJPywzU4JylpqgS6SoB9t21GZ4iN3bY2M6Qf10=.
I want to decrypt this: uSG1OxJPywzU4JylpqgS6SoB9t21GZ4iN3bY2M6Qf10=
Thanks in advance.

Try this code,it works fine on my pc.Good luck!
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
public class AESExample
{
public static void main(String[] args)
{
try
{
String plainData = "my name is laksahan", cipherText, decryptedText;
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey secretKey = keyGen.generateKey();
cipherText = encrypt(plainData, secretKey);
System.out.println(cipherText);
decryptedText = decrypt(cipherText, secretKey);
System.out.println(decryptedText);
} catch (Exception e)
{
e.printStackTrace();
}
}
public static String encrypt(String plainData, SecretKey secretKey) throws Exception
{
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] byteDataToEncrypt = plainData.getBytes();
byte[] byteCipherText = aesCipher.doFinal(byteDataToEncrypt);
return new BASE64Encoder().encode(byteCipherText);
}
public static String decrypt(String cipherData, SecretKey secretKey) throws Exception
{
byte[] data = new BASE64Decoder().decodeBuffer(cipherData);
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] plainData = aesCipher.doFinal(data);
return new String(plainData);
}
}
If you want to use a customer key,try the following code,just remember the key length is 128 bit.
By the way ,I prefer to store my key in keystore file!
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;
public class AESExample
{
public static void main(String[] args)
{
try
{
byte[]key={-4, -14, 106, -75, -9, 65, -95, 77, -52, 73, -87, -101, 80, 94, -59, -66};
String plainData = "my name is laksahan", cipherText, decryptedText;
System.out.println(key.length);
cipherText = encrypt(plainData, key);
System.out.println(cipherText);
decryptedText = decrypt(cipherText, key);
System.out.println(decryptedText);
} catch (Exception e)
{
e.printStackTrace();
}
}
public static String encrypt(String plainData, byte[] key) throws Exception
{
Cipher aesCipher = Cipher.getInstance("AES");
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
aesCipher.init(Cipher.ENCRYPT_MODE, keySpec);
byte[] byteDataToEncrypt = plainData.getBytes();
byte[] byteCipherText = aesCipher.doFinal(byteDataToEncrypt);
return new BASE64Encoder().encode(byteCipherText);
}
public static String decrypt(String cipherData, byte[] key) throws Exception
{
byte[] data = new BASE64Decoder().decodeBuffer(cipherData);
SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.DECRYPT_MODE, keySpec);
byte[] plainData = aesCipher.doFinal(data);
return new String(plainData);
}
}

try this
byte[] data = new BASE64Decoder().decodeBuffer(cipherData);
Cipher aesCipher = Cipher.getInstance("AES");
aesCipher.init(Cipher.DECRYPT_MODE, secretKeyUsed while encrypting);
byte[] plainData = aesCipher.doFinal(data);
return new String(plainData);

Related

BadPaddingException: pad block corrupted | BouncyCastle

I'm trying to decrypt data that is encrypted with AES/SIC/PKCS7Padding. I'm making use of BouncyCastleProvider to achieve this, but on decryption BadPaddingException is thrown.
Here's the code i'm using to decrypt, am i doing something wrong? Any help is appreciated, thanks!
public class AesEncryption {
public static String decrypt(String aesKey, String cipherText) {
try {
Security.addProvider(new BouncyCastleProvider());
Cipher dcipher;
SecretKey key = new SecretKeySpec(Base64.getDecoder().decode(aesKey), "AES");
dcipher = Cipher.getInstance("AES/SIC/PKCS7Padding", "BC");
dcipher.init(Cipher.DECRYPT_MODE, key, generateIv());
byte[] dec = Base64.getDecoder().decode(cipherText);
byte[] utf8 = dcipher.doFinal(dec);
return new String(utf8, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static IvParameterSpec generateIv() {
byte[] iv = new byte[16];
new SecureRandom().nextBytes(iv);
return new IvParameterSpec(iv);
}
}

Cipher - AES / CBC/PKCS5padding in PHP

I have following code in Java and i want to convert it into PHP.
Can someone tell how I should approach this ?
private static Cipher initCipher(final int mode, final String initialVectorString, final String secretKey)
throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException {
final SecretKeySpec skeySpec = new SecretKeySpec(secretKey.getBytes(), "AES");
final IvParameterSpec initialVector = new IvParameterSpec(initialVectorString.getBytes());
final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(mode, skeySpec, initialVector);
return cipher;
}
public static String encrypt(final String dataToEncrypt) {
String encryptedData = null;
try {
// Initialize the cipher
final Cipher cipher = initCipher(Cipher.ENCRYPT_MODE, iv, secretKey);
// Encrypt the data
final byte[] encryptedByteArray = cipher.doFinal(dataToEncrypt.getBytes());
// Encode using Base64
encryptedData = (new BASE64Encoder()).encode(encryptedByteArray);
} catch (Exception e) {
System.err.println("Problem encrypting the data");
e.printStackTrace();
}
return encryptedData;
}

How to Encrypt/Decrypt text in a file in Java

I have a problem with my code, when I encrypt data, for example, in this case, the simmetric key I encrypted with the receiver's public key, then saved to a text file, when I read that text file and try to decrypt it, using the receiver's private key, I get a different key, therefore I cannot use it to decrypt the encrypted message.
Sender's code:
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.KeyStore;
import java.security.MessageDigest;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
class Sender{
public static void main(String[] args) {
//infile.txt
File inFile = new File(args[0]);
//outfile.txt
File outFile = new File(args[1]);
//mykeystore.jks
File keyStoreFile = new File(args[2]);
//mykeystore info
String alias = args[3];
String password = args[4];
String storepass = args[5];
//receptor certificate
String receptorCert = args[6];
try {
//Read plain text
FileInputStream rawDataFromFile = new FileInputStream(inFile);
byte[] plainText = new byte[(int) inFile.length()];
rawDataFromFile.read(plainText);
//Create simmetric key
String key = "Bar12345Bar12345"; // 128 bit key
String initVector = "RandomInitVector"; // 16 bytes IV
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
//Encrypt plaintext
byte[] ciphertext = cipher.doFinal(plainText);
//Hash plaintext
MessageDigest md = MessageDigest.getInstance("SHA");
md.update(plainText);
byte[] digest = md.digest();
//Encrypt simmetric key with receiver's public key
Cipher rsaCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
PublicKey receptorPublicKey = getPublicKeyFromCert(receptorCert);
rsaCipher.init(Cipher.ENCRYPT_MODE, receptorPublicKey);
byte[] simmetricKey = rsaCipher.doFinal(skeySpec.getEncoded());
//Encrypt hash with my private key
KeyStore myKeyStore = KeyStore.getInstance("JKS");
FileInputStream inStream = new FileInputStream(keyStoreFile);
myKeyStore.load(inStream, storepass.toCharArray());
PrivateKey privatekey = (PrivateKey) myKeyStore.getKey(alias, password.toCharArray());
rsaCipher.init(Cipher.ENCRYPT_MODE, privatekey);
byte[] encodedHash = rsaCipher.doFinal(digest);
//Write to outputfile
FileOutputStream outToFile = new FileOutputStream(outFile);
outToFile.write(simmetricKey);
outToFile.write(encodedHash);
outToFile.write(ciphertext);
outToFile.close();
rawDataFromFile.close();
} catch (Exception e) {
e.printStackTrace();
e.getMessage();
}
}
public static PublicKey getPublicKeyFromCert(String certLocation) {
PublicKey pub = null;
try {
InputStream inStream = new FileInputStream(certLocation);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate) cf.generateCertificate(inStream);
inStream.close();
pub = (PublicKey) cert.getPublicKey();
} catch (Exception e) {
e.printStackTrace();
}
return pub;
}
}
Receiver's code:
import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.security.PrivateKey;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class Receiver {
public static void main(String[] args) {
//Sender's out file
File inFile = new File(args[0]);
//receiver's keystore
File keyStoreFile = new File(args[1]);
//receiver's keystore info
String password = args[2];
String alias = args[3];
String storepass = args[4];
//sender's cetificate
File cert = new File(args[5]);
try {
//get Sender's out file
FileInputStream rawDataFromFile = new FileInputStream(inFile);
byte[] simmetricKey = new byte[256];
byte[] hash = new byte[256];
byte[] message;
rawDataFromFile.read(simmetricKey);
rawDataFromFile.read(hash);
int b = rawDataFromFile.available();
message = new byte[b];
rawDataFromFile.read(message);
//decrypt the simmetric key with receiver's private key
KeyStore myKeyStore = KeyStore.getInstance("JKS");
FileInputStream inStream = new FileInputStream(keyStoreFile);
myKeyStore.load(inStream, storepass.toCharArray());
PrivateKey privatekey = (PrivateKey) myKeyStore.getKey(alias, password.toCharArray());
//
Cipher deCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
deCipher.init(Cipher.DECRYPT_MODE, privatekey);
byte[] key = deCipher.doFinal(simmetricKey);
System.out.println(Base64.encodeBase64String(key));
} catch (Exception e) {
System.out.println("Error del sistema " + e);
e.printStackTrace();
}
}
}
UPDATE:
Now I can decrypt the simmetric key using the receiver's private key. But I dont know how to create a decoder using the same argument when I encrypted the message.
Sender's code to encrypt plain text.
String key = "Bar12345Bar12345"; // 128 bit key
String initVector = "RandomInitVector"; // 16 bytes IV
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
System.out.println(iv.getIV());
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] ciphertext = cipher.doFinal(plainText);
Receiver's decryption 1
SecretKeySpec keySpec = new SecretKeySpec(decryptedKeySpec, "AES");
Cipher decoder = Cipher.getInstance("AES");
decoder.init(Cipher.DECRYPT_MODE, keyspec);
byte[] original = descipher.doFinal(message);
ERROR: Given final block not properly padded
Receiver's decryption 2
SecretKeySpec keySpec = new SecretKeySpec(decryptedKeySpec, "AES");
Cipher decoder = Cipher.getInstance("AES/CBC/PKCS5PADDING");
decoder.init(Cipher.DECRYPT_MODE, keyspec);
byte[] original = descipher.doFinal(message);
ERROR: Parameters missing
FINAL UPDATE:
Now my code works, thanks for all the help.
This code can be downloaded from here (btw, it's in spanish, but i don't think it matters):
download
The issue is you are using AES to encrypt
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
whereas to decipher,
you are using RSA,
Cipher deCipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
Code snippet to use for encrypt/decrypt using AES
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
public class EncryptionDecryptionAES {
static Cipher cipher;
public static void main(String[] args) throws Exception {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(128);
SecretKey secretKey = keyGenerator.generateKey();
cipher = Cipher.getInstance("AES");
String plainText = "AES Symmetric Encryption Decryption";
System.out.println("Plain Text Before Encryption: " + plainText);
String encryptedText = encrypt(plainText, secretKey);
System.out.println("Encrypted Text After Encryption: " + encryptedText);
String decryptedText = decrypt(encryptedText, secretKey);
System.out.println("Decrypted Text After Decryption: " + decryptedText);
}
public static String encrypt(String plainText, SecretKey secretKey)
throws Exception {
byte[] plainTextByte = plainText.getBytes();
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encryptedByte = cipher.doFinal(plainTextByte);
Base64.Encoder encoder = Base64.getEncoder();
String encryptedText = encoder.encodeToString(encryptedByte);
return encryptedText;
}
public static String decrypt(String encryptedText, SecretKey secretKey)
throws Exception {
Base64.Decoder decoder = Base64.getDecoder();
byte[] encryptedTextByte = decoder.decode(encryptedText);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedByte = cipher.doFinal(encryptedTextByte);
String decryptedText = new String(decryptedByte);
return decryptedText;
}
}
Please check http://javapapers.com/java/java-symmetric-aes-encryption-decryption-using-jce/
It seems that your receiver tries to read 256 byte for the encrypted symmetric key, but I think the RSA encrypted key only is 128 byte long.
So maybe it works using
byte[] simmetricKey = new byte[128];

How to use Cipher on this Method to decrypt a String?

Hello I build this 2 Methods the Encryption works fine but the Decryption get an error because
cipher wants a byte and i want to encrypt from a String
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Test {
private byte[] encrypted;
private String encryptedtext;
private String decrypted;
public String Encrypt (String pInput) {
try {
String Input = pInput;
String key = "Bar12345Bar12345Bar12345Bar12345";
// Erstelle key and cipher
SecretKeySpec aesKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
// Verschlüsselung
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] encrypted = cipher.doFinal(Input.getBytes());
encryptedtext = new String(encrypted);
System.err.println("encrypted:" + encryptedtext);
}catch(Exception e) {
e.printStackTrace();
}
return encrypted;
}
public String Decrypt (String pInput) {
try {
String Input = pInput;
String key = "Bar12345Bar12345Bar12345Bar12345";
// Erstelle key and cipher
SecretKeySpec aesKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
// Entschlüsselung
cipher.init(Cipher.DECRYPT_MODE, aesKey);
decrypted = new String(cipher.doFinal(encryptedtext)); // HERE IS THE PROBLEM IT WANT BYTE BUT I WANT TO ENCRYPT FROM A STRING
System.err.println("decrypted: " + decrypted);
}catch(Exception e) {
e.printStackTrace();
}
return pInput;
}
}
Byte array cannot directly convert to string, and neither do the reverse direction.
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;
public class stackoverflow_test {
private byte[] encrypted;
private String encryptedtext;
private String decrypted;
public String Encrypt(String pInput) {
try {
String Input = pInput;
String key = "Bar12345Bar12345Bar12345Bar12345";
SecretKeySpec aesKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, aesKey);
byte[] encrypted = cipher.doFinal(Input.getBytes());
//encryptedtext = new String(encrypted);
encryptedtext = DatatypeConverter.printBase64Binary(encrypted);
System.err.println("encrypted:" + encryptedtext);
} catch (Exception e) {
e.printStackTrace();
}
return encryptedtext;
}
public String Decrypt(String pInput) {
try {
String Input = pInput;
String key = "Bar12345Bar12345Bar12345Bar12345";
SecretKeySpec aesKey = new SecretKeySpec(key.getBytes(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, aesKey);
encrypted = DatatypeConverter.parseBase64Binary(encryptedtext);
decrypted = new String(cipher.doFinal(encrypted));
System.err.println("decrypted: " + decrypted);
} catch (Exception e) {
e.printStackTrace();
}
return pInput;
}
public static void main(String[] ag){
stackoverflow_test test = new stackoverflow_test();
String a = test.Encrypt("Byte cannot directly convert to string");
String b = test.Decrypt(a);
}
}
Result
encrypted:UmH+3eUagjrRDblxSStArnaktoxTLX+7qvPdwiTO7VggYmYtuXu/Ygww8ZG5SrDz
decrypted: Byte cannot directly convert to string
You can use Cipher to encrypt and decrypt a String.
public class CryptUtil {
private static final String ALGORITHM = "Blowfish";
private static final String MODE = "Blowfish/CBC/PKCS5Padding";
private static final String IV = "abcdefgh";
public static String encrypt(String secretKey, String value ) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(MODE);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, new IvParameterSpec(IV.getBytes()));
byte[] values = cipher.doFinal(value.getBytes());
return Base64.encodeToString(values, Base64.DEFAULT);
}
public static String decrypt(String secretKey, String value) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
byte[] values = Base64.decode(value, Base64.DEFAULT);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(), ALGORITHM);
Cipher cipher = Cipher.getInstance(MODE);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new IvParameterSpec(IV.getBytes()));
return new String(cipher.doFinal(values));
}
}

Image encryption/decryption using AES256 symmetric block ciphers [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Is there any good example of how to encrypt and decrypt image and other files with AES on Android?
Warning: This answer contains code you should not use as it is insecure (using SHA1PRNG for key derivation and using AES in ECB mode)
Instead (as of 2016), use PBKDF2WithHmacSHA1 for key derivation and AES in CBC or GCM mode (GCM provides both privacy and integrity)
You could use functions like these:
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;
}
And invoke them like this:
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos); // bm is the bitmap object
byte[] b = baos.toByteArray();
byte[] keyStart = "this is a key".getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();
// encrypt
byte[] encryptedData = encrypt(key,b);
// decrypt
byte[] decryptedData = decrypt(key,encryptedData);
This should work, I use similar code in a project right now.
As mentioned by Nacho.L PBKDF2WithHmacSHA1 derivation is used as it is more secured.
import android.util.Base64;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class AESEncyption {
private static final int pswdIterations = 10;
private static final int keySize = 128;
private static final String cypherInstance = "AES/CBC/PKCS5Padding";
private static final String secretKeyInstance = "PBKDF2WithHmacSHA1";
private static final String plainText = "sampleText";
private static final String AESSalt = "exampleSalt";
private static final String initializationVector = "8119745113154120";
public static String encrypt(String textToEncrypt) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(getRaw(plainText, AESSalt), "AES");
Cipher cipher = Cipher.getInstance(cypherInstance);
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(initializationVector.getBytes()));
byte[] encrypted = cipher.doFinal(textToEncrypt.getBytes());
return Base64.encodeToString(encrypted, Base64.DEFAULT);
}
public static String decrypt(String textToDecrypt) throws Exception {
byte[] encryted_bytes = Base64.decode(textToDecrypt, Base64.DEFAULT);
SecretKeySpec skeySpec = new SecretKeySpec(getRaw(plainText, AESSalt), "AES");
Cipher cipher = Cipher.getInstance(cypherInstance);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(initializationVector.getBytes()));
byte[] decrypted = cipher.doFinal(encryted_bytes);
return new String(decrypted, "UTF-8");
}
private static byte[] getRaw(String plainText, String salt) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance(secretKeyInstance);
KeySpec spec = new PBEKeySpec(plainText.toCharArray(), salt.getBytes(), pswdIterations, keySize);
return factory.generateSecret(spec).getEncoded();
} catch (InvalidKeySpecException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return new byte[0];
}
}
import java.security.AlgorithmParameters;
import java.security.SecureRandom;
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;
class SecurityUtils {
private static final byte[] salt = { (byte) 0xA4, (byte) 0x0B, (byte) 0xC8,
(byte) 0x34, (byte) 0xD6, (byte) 0x95, (byte) 0xF3, (byte) 0x13 };
private static int BLOCKS = 128;
public static byte[] encryptAES(String seed, String cleartext)
throws Exception {
byte[] rawKey = getRawKey(seed.getBytes("UTF8"));
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
return cipher.doFinal(cleartext.getBytes("UTF8"));
}
public static byte[] decryptAES(String seed, byte[] data) throws Exception {
byte[] rawKey = getRawKey(seed.getBytes("UTF8"));
SecretKeySpec skeySpec = new SecretKeySpec(rawKey, "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
return cipher.doFinal(data);
}
private static byte[] getRawKey(byte[] seed) throws Exception {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(BLOCKS, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
private static byte[] pad(byte[] seed) {
byte[] nseed = new byte[BLOCKS / 8];
for (int i = 0; i < BLOCKS / 8; i++)
nseed[i] = 0;
for (int i = 0; i < seed.length; i++)
nseed[i] = seed[i];
return nseed;
}
public static byte[] encryptPBE(String password, String cleartext)
throws Exception {
SecretKeyFactory factory = SecretKeyFactory
.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 1024, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
return cipher.doFinal(cleartext.getBytes("UTF-8"));
}
public static String decryptPBE(SecretKey secret, String ciphertext,
byte[] iv) throws Exception {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
return new String(cipher.doFinal(ciphertext.getBytes()), "UTF-8");
}
}
For AES/CBC/PKCS7 encryption/decryption, Just Copy and paste the following code and replace SecretKey and IV with your own.
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import android.util.Base64;
public class CryptoHandler {
String SecretKey = "xxxxxxxxxxxxxxxxxxxx";
String IV = "xxxxxxxxxxxxxxxx";
private static CryptoHandler instance = null;
public static CryptoHandler getInstance() {
if (instance == null) {
instance = new CryptoHandler();
}
return instance;
}
public String encrypt(String message) throws NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException,
BadPaddingException, InvalidKeyException,
UnsupportedEncodingException, InvalidAlgorithmParameterException {
byte[] srcBuff = message.getBytes("UTF8");
//here using substring because AES takes only 16 or 24 or 32 byte of key
SecretKeySpec skeySpec = new
SecretKeySpec(SecretKey.substring(0,32).getBytes(), "AES");
IvParameterSpec ivSpec = new
IvParameterSpec(IV.substring(0,16).getBytes());
Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
ecipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivSpec);
byte[] dstBuff = ecipher.doFinal(srcBuff);
String base64 = Base64.encodeToString(dstBuff, Base64.DEFAULT);
return base64;
}
public String decrypt(String encrypted) throws NoSuchAlgorithmException,
NoSuchPaddingException, InvalidKeyException,
InvalidAlgorithmParameterException, IllegalBlockSizeException,
BadPaddingException, UnsupportedEncodingException {
SecretKeySpec skeySpec = new
SecretKeySpec(SecretKey.substring(0,32).getBytes(), "AES");
IvParameterSpec ivSpec = new
IvParameterSpec(IV.substring(0,16).getBytes());
Cipher ecipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
ecipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec);
byte[] raw = Base64.decode(encrypted, Base64.DEFAULT);
byte[] originalBytes = ecipher.doFinal(raw);
String original = new String(originalBytes, "UTF8");
return original;
}
}
Old question but I upgrade the answers supporting Android prior and post 4.2 and considering all recent changes according to Android developers blog
Plus I leave a working example on my github repo.
import java.nio.charset.Charset;
import java.security.AlgorithmParameters;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
/*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will Google be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, as long as the origin is not misrepresented.
*
* #author: Ricardo Champa
*
*/
public class MyCipher {
private final static String ALGORITHM = "AES";
private String mySecret;
public MyCipher(String mySecret){
this.mySecret = mySecret;
}
public MyCipherData encryptUTF8(String data){
try{
byte[] bytes = data.toString().getBytes("utf-8");
byte[] bytesBase64 = Base64.encodeBase64(bytes);
return encrypt(bytesBase64);
}
catch(Exception e){
MyLogs.show(e.getMessage());
return null;
}
}
public String decryptUTF8(byte[] encryptedData, IvParameterSpec iv){
try {
byte[] decryptedData = decrypt(encryptedData, iv);
byte[] decodedBytes = Base64.decodeBase64(decryptedData);
String restored_data = new String(decodedBytes, Charset.forName("UTF8"));
return restored_data;
} catch (Exception e) {
MyLogs.show(e.getMessage());;
return null;
}
}
//AES
private MyCipherData encrypt(byte[] raw, byte[] clear) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, ALGORITHM);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//solved using PRNGFixes class
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] data = cipher.doFinal(clear);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
return new MyCipherData(data, iv);
}
private byte[] decrypt(byte[] raw, byte[] encrypted, IvParameterSpec iv) throws Exception {
SecretKeySpec skeySpec = new SecretKeySpec(raw, ALGORITHM);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec, iv);
byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
private byte[] getKey() throws Exception{
byte[] keyStart = this.mySecret.getBytes("utf-8");
KeyGenerator kgen = KeyGenerator.getInstance(ALGORITHM);
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
// if (android.os.Build.VERSION.SDK_INT >= 17) {
// sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
// } else {
// sr = SecureRandom.getInstance("SHA1PRNG");
// }
sr.setSeed(keyStart);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();
return key;
}
////////////////////////////////////////////////////////////
private MyCipherData encrypt(byte[] data) throws Exception{
return encrypt(getKey(),data);
}
private byte[] decrypt(byte[] encryptedData, IvParameterSpec iv) throws Exception{
return decrypt(getKey(),encryptedData, iv);
}
}
If you are encrypting a text file, then the following test/sample may be useful. It does the following:
Create a byte stream,
wraps that with AES encryption,
wrap it next with text processing
and lastly buffers it
// AESdemo
public class AESdemo extends Activity {
boolean encryptionIsOn = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aesdemo);
// needs <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
String homeDirName = Environment.getExternalStorageDirectory().getAbsolutePath() +
"/" + getPackageName();
File file = new File(homeDirName, "test.txt");
byte[] keyBytes = getKey("password");
try {
File dir = new File(homeDirName);
if (!dir.exists())
dir.mkdirs();
if (!file.exists())
file.createNewFile();
OutputStreamWriter osw;
if (encryptionIsOn) {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
FileOutputStream fos = new FileOutputStream(file);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);
osw = new OutputStreamWriter(cos, "UTF-8");
}
else // not encryptionIsOn
osw = new FileWriter(file);
BufferedWriter out = new BufferedWriter(osw);
out.write("This is a test\n");
out.close();
}
catch (Exception e) {
System.out.println("Encryption Exception "+e);
}
///////////////////////////////////
try {
InputStreamReader isr;
if (encryptionIsOn) {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
SecretKeySpec secretKeySpec = new SecretKeySpec(keyBytes, "AES");
IvParameterSpec ivParameterSpec = new IvParameterSpec(keyBytes);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
FileInputStream fis = new FileInputStream(file);
CipherInputStream cis = new CipherInputStream(fis, cipher);
isr = new InputStreamReader(cis, "UTF-8");
}
else
isr = new FileReader(file);
BufferedReader in = new BufferedReader(isr);
String line = in.readLine();
System.out.println("Text read: <"+line+">");
in.close();
}
catch (Exception e) {
System.out.println("Decryption Exception "+e);
}
}
private byte[] getKey(String password) throws UnsupportedEncodingException {
String key = "";
while (key.length() < 16)
key += password;
return key.substring(0, 16).getBytes("UTF-8");
}
}
AES encrypt/decrypt in android
String encData= encrypt("keykey".getBytes("UTF-16LE"), ("0123000000000215").getBytes("UTF-16LE"));
String decData= decrypt("keykey",Base64.decode(encData.getBytes("UTF-16LE"), Base64.DEFAULT));
encrypt function
private static String encrypt(byte[] key, byte[] clear) throws Exception
{
MessageDigest md = MessageDigest.getInstance("md5");
byte[] digestOfPassword = md.digest(key);
SecretKeySpec skeySpec = new SecretKeySpec(digestOfPassword, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
byte[] encrypted = cipher.doFinal(clear);
return Base64.encodeToString(encrypted,Base64.DEFAULT);
}
decrypt function
private static String decrypt(String key, byte[] encrypted) throws Exception
{
MessageDigest md = MessageDigest.getInstance("md5");
byte[] digestOfPassword = md.digest(key.getBytes("UTF-16LE"));
SecretKeySpec skeySpec = new SecretKeySpec(digestOfPassword, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS7Padding");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
byte[] decrypted = cipher.doFinal(encrypted);
return new String(decrypted, "UTF-16LE");
}
AES encrypt/decrypt in c#
static void Main(string[] args)
{
string enc = encryptAES("0123000000000215", "keykey");
string dec = decryptAES(enc, "keykey");
Console.ReadKey();
}
encrypt function
public static string encryptAES(string input, string key)
{
var plain = Encoding.Unicode.GetBytes(input);
// 128 bits
AesCryptoServiceProvider provider = new AesCryptoServiceProvider();
provider.KeySize = 128;
provider.Mode = CipherMode.ECB;
provider.Padding = PaddingMode.PKCS7;
provider.Key = CalculateMD5Hash(key);
var enc = provider.CreateEncryptor().TransformFinalBlock(plain, 0, plain.Length);
return Convert.ToBase64String(enc);
}
decrypt function
public static string decryptAES(string encryptText, string key)
{
byte[] enc = Convert.FromBase64String(encryptText);
// 128 bits
AesCryptoServiceProvider provider = new AesCryptoServiceProvider();
provider.KeySize = 128;
provider.Mode = CipherMode.ECB;
provider.Padding = PaddingMode.PKCS7;
provider.Key = CalculateMD5Hash(key);
var dec = provider.CreateDecryptor().TransformFinalBlock(enc, 0, enc.Length);
return Encoding.Unicode.GetString(dec);
}
create md5
public static byte[] CalculateMD5Hash(string input)
{
MD5 md5 = MD5.Create();
byte[] inputBytes = Encoding.Unicode.GetBytes(input);
return md5.ComputeHash(inputBytes);
}
Simple API to perform AES encryption on Android. This is the Android counterpart to the AESCrypt library Ruby and Obj-C (with the same defaults):
https://github.com/scottyab/AESCrypt-Android
Here is simple code snippet working for AES Encryption and Decryption.
import android.util.Base64;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class AESEncryptionClass {
private static String INIT_VECTOR_PARAM = "#####";
private static String PASSWORD = "#####";
private static String SALT_KEY = "#####";
private static SecretKeySpec generateAESKey() throws NoSuchAlgorithmException, InvalidKeySpecException {
// Prepare password and salt key.
char[] password = new String(Base64.decode(PASSWORD, Base64.DEFAULT)).toCharArray();
byte[] salt = new String(Base64.decode(SALT_KEY, Base64.DEFAULT)).getBytes(StandardCharsets.UTF_8);
// Create object of [Password Based Encryption Key Specification] with required iteration count and key length.
KeySpec spec = new PBEKeySpec(password, salt, 64, 256);
// Now create AES Key using required hashing algorithm.
SecretKey key = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1").generateSecret(spec);
// Get encoded bytes of secret key.
byte[] bytesSecretKey = key.getEncoded();
// Create specification for AES Key.
SecretKeySpec secretKeySpec = new SecretKeySpec(bytesSecretKey, "AES");
return secretKeySpec;
}
/**
* Call this method to encrypt the readable plain text and get Base64 of encrypted bytes.
*/
public static String encryptMessage(String message) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException {
byte[] initVectorParamBytes = new String(Base64.decode(INIT_VECTOR_PARAM, Base64.DEFAULT)).getBytes(StandardCharsets.UTF_8);
Cipher encryptionCipherBlock = Cipher.getInstance("AES/CBC/PKCS5Padding");
encryptionCipherBlock.init(Cipher.ENCRYPT_MODE, generateAESKey(), new IvParameterSpec(initVectorParamBytes));
byte[] messageBytes = message.getBytes();
byte[] cipherTextBytes = encryptionCipherBlock.doFinal(messageBytes);
String encryptedText = Base64.encodeToString(cipherTextBytes, Base64.DEFAULT);
return encryptedText;
}
/**
* Call this method to decrypt the Base64 of encrypted message and get readable plain text.
*/
public static String decryptMessage(String base64Cipher) throws BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeySpecException, InvalidAlgorithmParameterException, InvalidKeyException {
byte[] initVectorParamBytes = new String(Base64.decode(INIT_VECTOR_PARAM, Base64.DEFAULT)).getBytes(StandardCharsets.UTF_8);
Cipher decryptionCipherBlock = Cipher.getInstance("AES/CBC/PKCS5Padding");
decryptionCipherBlock.init(Cipher.DECRYPT_MODE, generateAESKey(), new IvParameterSpec(initVectorParamBytes));
byte[] cipherBytes = Base64.decode(base64Cipher, Base64.DEFAULT);
byte[] messageBytes = decryptionCipherBlock.doFinal(cipherBytes);
String plainText = new String(messageBytes);
return plainText;
}
}
Now, call encryptMessage() or decryptMessage() for desired AES Operation with required parameters.
Also, handle the exceptions during AES operations.
Hope it helped...
To add bouncy castle to Android project: https://mvnrepository.com/artifact/org.bouncycastle/bcprov-jdk16/1.45
Add this line in your Main Activity:
static {
Security.addProvider(new BouncyCastleProvider());
}
public class AESHelper {
private static final String TAG = "AESHelper";
public static byte[] encrypt(byte[] data, String initVector, String key) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
Cipher c = Cipher.getInstance("AES/CBC/PKCS5PADDING");
SecretKeySpec k = new SecretKeySpec(Base64.decode(key, Base64.DEFAULT), "AES");
c.init(Cipher.ENCRYPT_MODE, k, iv);
return c.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static byte[] decrypt(byte[] data, String initVector, String key) {
try {
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
Cipher c = Cipher.getInstance("AES/CBC/PKCS5PADDING");
SecretKeySpec k = new SecretKeySpec(Base64.decode(key, Base64.DEFAULT), "AES");
c.init(Cipher.DECRYPT_MODE, k, iv);
return c.doFinal(data);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static String keyGenerator() throws NoSuchAlgorithmException {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(192);
return Base64.encodeToString(keyGenerator.generateKey().getEncoded(),
Base64.DEFAULT);
}
}

Categories