I was using this code segment to encrypt my image data 2 years ago. At that time my target SDK was 22. But When i try to update my SDK i face that i can not decrypt it. I find out that Android deprecated this encryption method. Is there any way to solve this problem so that i can decrypt my images.
Thanks in advance.
public byte[] EncryptByte(byte[] rawInputByte){
byte[] fileBytes = null;
try {
byte[] yourKey = generateKey("password");
fileBytes = encodeFile(yourKey, rawInputByte);
} catch (Exception e) {
e.printStackTrace();
}
return fileBytes;
}
public byte[] generateKey(String password) throws Exception
{
byte[] keyStart = password.getBytes("UTF-8");
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "Crypto");
sr.setSeed(keyStart);
kgen.init(128, sr);
SecretKey skey = kgen.generateKey();
return skey.getEncoded();
}
At last i can solve this. Thanks James K Polk for giving me the link. My code segment is given below and InsecureSHA1PRNGKeyDerivator link is this. Hope it will help you guys.
public byte[] decodeFile(byte[] fileData) throws Exception
{
SecretKey insecureKey = deriveKeyInsecurely("password", 16);
byte[] decryptedData = decryptData(fileData, insecureKey);
return decryptedData;
}
#RequiresApi(api = Build.VERSION_CODES.KITKAT)
private static SecretKey deriveKeyInsecurely(String password, int
keySizeInBytes) throws Exception {
byte[] passwordBytes = password.getBytes(StandardCharsets.US_ASCII);
return new SecretKeySpec( InsecureSHA1PRNGKeyDerivator.deriveInsecureKey( passwordBytes, keySizeInBytes), "AES");
}
private static byte[] decryptData(
byte[] data, SecretKey key) {
try {
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, key );
return cipher.doFinal(data);
} catch (GeneralSecurityException e) {
throw new RuntimeException("This is unconceivable!", e);
}
}
Related
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);
}
}
I try to use java7 to achieve AES-256-GCM decoding
I encountered a mac check failure response in GCM
Please help me out, thank you all.
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
public static void main(String[] args) throws Exception {
String iv = "35d117c42d1c1835420b6b9942dd4f1b"; // utf-8
String key = "3a7bd3e2360a3d29eea436fcfb7e44c7"; // utf-8
String hexCipherString = "07a604fc0c143a6e"; // hex
String hexAuthTagString = "984e81176ff260717beb184db3d73753"; //hex
byte[] decodedCipherHexBtye = Hex.decodeHex(hexCipherString.toCharArray());
byte[] base64Cipher = Base64.decodeBase64(decodedCipherHexBtye);
byte[] decodedAuthTagHex = Hex.decodeHex(hexAuthTagString.toCharArray());
byte[] base64AuthTag = Base64.decodeBase64(decodedAuthTagHex);
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
byte[] gcmIv = iv.getBytes("UTF-8");
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
GCMParameterSpec params = new GCMParameterSpec(base64AuthTag.length * Byte.SIZE, gcmIv);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, params);
cipher.updateAAD(base64AuthTag);
byte[] result = cipher.doFinal(base64Cipher);
System.out.println(Base64.encodeBase64(result));
}
I am looking forward to the expected result of Base64Encode: dGVzdA==
How to address the Security warning comment to implement safe code.
The core issue in the warning is the need for a randomly generated IV (a set of truly random bytes) for each encryption
when you make a Cypher here is a concrete example using Java 8 Oracle SE
val cipher = Cipher.getInstance("some scheme", "some provider");
then when we use the the Cypher safely we need a true random initialization vector IV to correctly resolve the issue this warning is directing us too,
turns out at least in Oracle Java 8 this is easy,
with the above cypher
cipher.getIV()
the instance method for the cipher object is safe see
generally use with IvParameterSpec
ivParams = IvParameterSpec( cipher.getIV())
cipher.init(Cipher.ENCRYPT_MODE, key, ivParams);
I found a solution and modified the code as follows:
public static void main(String[] args) throws Exception {
String iv = "35d117c42d1c1835420b6b9942dd4f1b"; // utf-8
String key = "3a7bd3e2360a3d29eea436fcfb7e44c7"; // utf-8
String hexCipherString = "07a604fc0c143a6e"; // hex
String hexAuthTagString = "984e81176ff260717beb184db3d73753"; //hex
byte[] decodedCipherHexBtye = Hex.decodeHex(hexCipherString.toCharArray());
byte[] decodedAuthTagHex = Hex.decodeHex(hexAuthTagString.toCharArray());
SecretKeySpec skeySpec = new SecretKeySpec(key.getBytes("UTF-8"), "AES");
byte[] gcmIv = iv.getBytes("UTF-8");
Security.addProvider(new BouncyCastleProvider());
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "BC");
GCMParameterSpec params = new GCMParameterSpec(decodedAuthTagHex.length * Byte.SIZE, gcmIv);
cipher.init(Cipher.DECRYPT_MODE, skeySpec, params);
cipher.update(decodedCipherHexBtye);
byte[] result = cipher.doFinal(decodedAuthTagHex);
System.out.println(new String(result));
}
Refer to this article
Tag mismatch error in AES-256-GCM Decryption using Java
This is the easiest way to encryption and decryption using AES-256.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
String decryptedData = AESUtils.decrypt("Your Encrypted Data");
System.out.println(decryptedData);
}
public class AESUtils {
private static final String ENCRYPTION_KEY = "RwcmlVpg";
private static final String ENCRYPTION_IV = "5183666c72eec9e4";
#RequiresApi(api = Build.VERSION_CODES.O)
public static String encrypt(String src) {
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, makeKey(), makeIv());
byte[] origignal= Base64.encode(cipher.doFinal(src.getBytes()),Base64.DEFAULT);
return new String(origignal);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
#RequiresApi(api = Build.VERSION_CODES.O)
public static String decrypt(String src) {
String decrypted = "";
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, makeKey(), makeIv());
byte[] decode = Base64.decode(src, Base64.NO_WRAP);
decrypted= new String(cipher.doFinal(decode), "UTF-8");
} catch (Exception e) {
Log.v("AES Exception", String.valueOf(e));
throw new RuntimeException(e);
}
return decrypted;
}
static AlgorithmParameterSpec makeIv() {
try {
return new IvParameterSpec(ENCRYPTION_IV.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
static Key makeKey() {
try {
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] key = md.digest(ENCRYPTION_KEY.getBytes("UTF-8"));
return new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
}
}
I am trying to decrypt the data in Java which was encrypted in PHP using AES-256-CBC. Decrypt method of Java cipher.doFinal throwing IllegalBlockSizeException. Can anyone help me to resolve this? Banging my head to fix this from the past 2 days. Please let me know if need more info.
public static String decrypt(String encryptedResult, String secretKey, String iv) {
String decrypted;
try {
byte[] bytes = new BigInteger(encryptedResult.trim(),16).toByteArray();
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, makeKey(secretKey), makeIv(iv));
byte[] bytesFinal = cipher.doFinal(bytes);
decrypted = new String(bytesFinal);
} catch (Exception e) {
throw new RuntimeException(e);
}
return decrypted;
}
static AlgorithmParameterSpec makeIv(String iv) {
try {
return new IvParameterSpec(iv.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
static Key makeKey(String secretKey) {
return new SecretKeySpec(secretKey.getBytes(), "AES");
}
I'm trying to load an AES SecretKey from a .pem file encrypted with a private key.
SecretKey loadAESKeyfromCertFile(String filename, PrivateKey prv) {
try {
FileInputStream in = new FileInputStream(filename);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, prv);
byte[] b = new byte[256];
in.read(b);
byte[] keyb = cipher.doFinal(b);
return new SecretKeySpec(keyb, "AES");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
But i keep getting java.security.InvalidKeyException: No installed provider supports this key: sun.security.rsa.RSAPrivateCrtKeyImpl
I have a problem with my code. I want to encrypt a message using a key made from passphrase. Then I want to send it (or use it somewhere, whatever) in String form (the encrypted one), and after that I want to decrypt it only by knowing the passphrase.
I wrote the code below, but I receive either IllegalBlockSizeException or BadPaddingException. I thought that badding would be took care by padding.
Here is my code:
Constructor and initialization:
public class AES_Cipher {
private String keyString;
private byte[] byteKey;
private SecretKey key;
Cipher c;
public AES_Cipher(String keyString){
this.keyString = keyString.toString();
}
public void init() throws InitializtionFailedException{
try{
c = Cipher.getInstance("AES/ECB/PKCS5Padding");
byteKey = keyString.getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
byteKey = sha.digest(byteKey);
byteKey = Arrays.copyOf(byteKey, 16);
key = new SecretKeySpec(byteKey, "AES");
}catch(NoSuchAlgorithmException e){
throw new InitializtionFailedException();
}
}
Encrypt:
public String encrypt(String text) throws EncryptionException{
try{
c.init(Cipher.ENCRYPT_MODE, key);
byte[] tmp = c.doFinal( text.getBytes("UTF-8"));
return new String(tmp, "UTF-8");
}catch(IllegalBlockSizeException e){
throw new EncryptionException();
}
}
Decrypt:
public String decrypt(String text) throws DecryptionException{
try{
//byte[] decordedValue = new BASE64Decoder().decodeBuffer(text);
// tried too use it but with poor outcome
//c = Cipher.getInstance("AES/ECB/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE, key);
byte[] tmp1 = text.getBytes("UTF-8");
//byte[] tmp = c.doFinal("aaaaaaaaaaaaaaaa".getBytes());
//this returns BadPaddingException
byte[] tmp = c.doFinal(text.getBytes());
return new String(tmp, "UTF-8");
}catch(IllegalBlockSizeException e){
throw new DecryptionException();
}
}
Of course there are some more exceptions.
Also, I would like to later use this code on android, and It doesn't need to be AES if there is some other Ciphers that are maybe less effective but less troublesome. But not simple XOR if that's not too much too ask.
Thank you in advance.
Ok. Seems to work now thanks to Artjom B.
Constructor and inicialization:
public class AES_Cipher {
private String keyString;
private byte[] byteKey;
private SecretKey key;
Cipher c;
public AES_Cipher(String keyString){
this.keyString = keyString.toString();
}
public void init() throws InitializtionFailedException{
try{
c = Cipher.getInstance("AES/ECB/PKCS5Padding");
byteKey = keyString.getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-1");
byteKey = sha.digest(byteKey);
byteKey = Arrays.copyOf(byteKey, 16);
key = new SecretKeySpec(byteKey, "AES");
}catch(NoSuchAlgorithmException e){
throw new InitializtionFailedException();
}
}
Encryption:
public String encrypt(String text) throws EncryptionException{
try{
c.init(Cipher.ENCRYPT_MODE, key);
byte[] textByte = text.getBytes("UTF-8");
byte[] tmp = c.doFinal(textByte);
String return1 = Base64.encodeToString(tmp, Base64.DEFAULT);
return return1;
} // of course there is some exceptions catched down there
Decryption:
public String decrypt(String text) throws DecryptionException{
try{
c.init(Cipher.DECRYPT_MODE, key);
byte[] textByte = Base64.decode(text, Base64.DEFAULT);
byte[] tmp = c.doFinal(textByte);
return new String(tmp, "UTF-8");
}catch(IllegalBlockSizeException e){
Log.d("Exception", "IllegalBlockSizeException");
throw new DecryptionException();
} // wrote DecryptionException myself.
// also there is more Exceptions below
}