I have encrypted a file using below commands
openssl rand 32 > test.key
openssl enc -aes-256-cbc -iter 10000 -pbkdf2 -salt -in test.txt -out test.txt.enc -pass file:test.key
Now i am trying to decrypt it using java. tring since last few days but no success.
Can anyone help ?
my code
package test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.charset.Charset;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
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 org.apache.commons.io.IOUtils;
public class OpenSSlDecryptor {
private static final Charset ASCII = Charset.forName("ASCII");
private static final int INDEX_KEY = 0;
private static final int INDEX_IV = 1;
private static final int ITERATIONS = 10000;
private static final int ARG_INDEX_FILENAME = 0;
private static final int ARG_INDEX_PASSWORD = 1;
private static final int SALT_OFFSET = 8;
private static final int SALT_SIZE = 8;
private static final int CIPHERTEXT_OFFSET = SALT_OFFSET + SALT_SIZE;
private static final int KEY_SIZE_BITS = 256;
/**
* Thanks go to Ola Bini for releasing this source on his blog.
* The source was obtained from <a href="http://olabini.com/blog/tag/evp_bytestokey/">here</a> .
*/
public static byte[][] EVP_BytesToKey(final int key_len, final int iv_len, final MessageDigest md,
final byte[] salt, final byte[] data, final int count) {
final byte[][] both = new byte[2][];
final byte[] key = new byte[key_len];
int key_ix = 0;
final byte[] iv = new byte[iv_len];
int iv_ix = 0;
both[0] = key;
both[1] = iv;
byte[] md_buf = null;
int nkey = key_len;
int niv = iv_len;
int i = 0;
if (data == null) {
return both;
}
int addmd = 0;
for (;;) {
md.reset();
if (addmd++ > 0) {
md.update(md_buf);
}
md.update(data);
if (null != salt) {
md.update(salt, 0, 8);
}
md_buf = md.digest();
for (i = 1; i < count; i++) {
md.reset();
md.update(md_buf);
md_buf = md.digest();
}
i = 0;
if (nkey > 0) {
for (;;) {
if (nkey == 0) {
break;
}
if (i == md_buf.length) {
break;
}
key[key_ix++] = md_buf[i];
nkey--;
i++;
}
}
if (niv > 0 && i != md_buf.length) {
for (;;) {
if (niv == 0) {
break;
}
if (i == md_buf.length) {
break;
}
iv[iv_ix++] = md_buf[i];
niv--;
i++;
}
}
if (nkey == 0 && niv == 0) {
break;
}
}
for (i = 0; i < md_buf.length; i++) {
md_buf[i] = 0;
}
return both;
}
public static void main(final String[] args) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException {
final String fileName = "test.txt.enc";
final File f = new File(fileName );
try {
// --- read base 64 encoded file ---
List<String> lines = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(f))) {
//br returns as stream and convert it into a List
lines = br.lines().collect(Collectors.toList());
} catch (final IOException e) {
e.printStackTrace();
}
final StringBuilder sb = new StringBuilder();
for (final String line : lines) {
sb.append(line.trim());
}
final String random_bin_key = "test.key";
final byte[] passwordKey = IOUtils.toByteArray(new FileInputStream(random_bin_key));
// --- extract salt & encrypted ---
final byte[] headerSaltAndCipherText = sb.toString().getBytes();
// header is "Salted__", ASCII encoded, if salt is being used (the default)
final byte[] salt = Arrays.copyOfRange(
headerSaltAndCipherText, SALT_OFFSET, SALT_OFFSET + SALT_SIZE);
final byte[] encrypted = Arrays.copyOfRange(
headerSaltAndCipherText, CIPHERTEXT_OFFSET, headerSaltAndCipherText.length);
// --- specify cipher and digest for EVP_BytesToKey method ---
final Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding");
final MessageDigest md5 = MessageDigest.getInstance("MD5");
// --- create key and IV ---
// the IV is useless, OpenSSL might as well have use zero's
final byte[][] keyAndIV = EVP_BytesToKey(
KEY_SIZE_BITS / Byte.SIZE,
aesCBC.getBlockSize(),
md5,
salt,
passwordKey,
ITERATIONS);
final SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES");
final IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]);
// --- initialize cipher instance and decrypt ---
aesCBC.init(Cipher.DECRYPT_MODE, key, iv);
final byte[] decrypted = aesCBC.doFinal(encrypted);
final String answer = new String(decrypted);
System.out.println(answer);
} catch (final BadPaddingException e) {
System.out.println(e.getMessage());
} catch (final IllegalBlockSizeException e) {
System.out.println(e.getMessage());
} catch (final GeneralSecurityException e) {
System.out.println(e.getMessage());
} catch (final IOException e) {
System.out.println(e.getMessage());
}
}
Error i am getting
Given final block not properly padded. Such issues can arise if a bad key is used during decryption.
I refereed following link
tried with
` final Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding");
// strip off the salt and iv
final ByteBuffer buffer = ByteBuffer.wrap(encryptedText);
byte[] saltBytes = new byte[16];
buffer.get(saltBytes, 0, saltBytes.length);
saltBytes = Arrays.copyOfRange(saltBytes, 8, 16);
final byte[] ivBytes1 = new byte[cipher.getBlockSize()];
buffer.get(ivBytes1, 0, ivBytes1.length);
final int length = buffer.capacity() - 16 - ivBytes1.length;
// length = length+ 16 -(length%16);
final byte[] encryptedTextBytes = new byte[length];
buffer.get(encryptedTextBytes);
// Deriving the key
final SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
final PBEKeySpec spec = new PBEKeySpec(new String(password).toCharArray(), saltBytes, 10000,
256);
final SecretKey secretKey = factory.generateSecret(spec);
final SecretKeySpec secret = new SecretKeySpec(secretKey.getEncoded(), "AES");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivBytes1));
byte[] decryptedTextBytes = null;
try {
decryptedTextBytes = cipher.doFinal(encryptedTextBytes);
} catch (final IllegalBlockSizeException e) {
e.printStackTrace();
} catch (final BadPaddingException e) {
e.printStackTrace();
}
Getting badpadding exception
tried with PBKDF2WithHmacSHA256
still getting the error
javax.crypto.SecretKeyFactory
to do PBKDF2 in your Java code? – Michael"PBKDF2WithHmacSHA256"
? – Michael