I want to decrypt a String. Here my Decryption and Encryption methods.
public String encrypt(String message) throws Exception {
byte[] messageInBytes = message.getBytes();
encryptionCipher = Cipher.getInstance("AES/GCM/NoPadding");
encryptionCipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedBytes = encryptionCipher.doFinal(messageInBytes);
return encode(encryptedBytes);
}
public String decrypt(String encryptedMessage) throws Exception {
byte[] messageInBytes = decode(encryptedMessage);
Cipher decryptionCipher = Cipher.getInstance("AES/GCM/NoPadding");
GCMParameterSpec spec = new GCMParameterSpec(T_LEN , encryptionCipher.getIV());
decryptionCipher.init(Cipher.DECRYPT_MODE, key, spec);
byte[] decryptedBytes = decryptionCipher.doFinal(messageInBytes);
return new String(decryptedBytes);
}
Here the main:
public static void main(String[] args) {
try {
AES aes = new AES();
aes.convertStringKeyToSecretKey();
String encryptedMessage = aes.encrypt("Peter");
String decryptedMessage = aes.decrypt(encryptedMessage);
System.err.println("Encrypted Message : " + encryptedMessage);
System.err.println("Decrypted Message : " + decryptedMessage);
} catch (Exception ignored) {
}
}
When I change encryptedMessage to a own String like:
String decryptedMessage = aes.decrypt("xDFzl9HsenqKspdEbL/m9I5X6dqn");
It does nothing
I hope you can help me.
Best Regards
Christian
public static String encryptAES(String toEncrypt, final String key1, final String key2) throws Exception {
try {
byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec keySpec = new PBEKeySpec(key1.toCharArray(), key2.getBytes(), 65536, 256);
SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
return Base64.getEncoder().encodeToString(cipher.doFinal(toEncrypt.getBytes(StandardCharsets.UTF_8)));
} catch (Exception ex) {
throw new Exception(ex);
}
}
public static String decryptAES(String toDecrypt, final String key1, final String key2) throws Exception {
try {
byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec keySpec = new PBEKeySpec(key1.toCharArray(), key2.getBytes(), 65536, 256);
SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
return new String(cipher.doFinal(Base64.getDecoder().decode(toDecrypt)));
} catch (Exception ex) {
throw new Exception(ex);
}
}
Here you can still expand its secureness by creating your own IV Spec key, which should contain only 16 character.
Actually, this is how AES encryption worked for me, You can also check this repo in GitHub for additional encryption methods.
Related
I'm trying to encrypt a file using AES and Java Crypto Library. But this is the error Which happens while I'm decrypting the file: "Error while decrypting: javax.crypto.BadPaddingException: Given final block not properly padded. Such issues can arise if a bad key is used during decryption."
This is my code so far:
public static void encrypt(File input, String key, File output) {
try
{
byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(key.toCharArray(), key.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKey, ivspec);
FileInputStream inputStream = new FileInputStream(input);
byte[] inputBytes = new byte[(int) input.length()];
int count;
byte[] outputBytes = cipher.doFinal(inputBytes);
FileOutputStream outputStream = new FileOutputStream(output);
while ((count = inputStream.read(inputBytes, 0, inputBytes.length)) > 0)
{
outputStream.write(inputBytes, 0, count);
}
inputStream.close();
outputStream.close();
}
catch (Exception e)
{
System.out.println("Error while encrypting: " + e.toString());
}
}
public static void decrypt(File input, String key, File output)
{
try
{
byte[] iv = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
IvParameterSpec ivspec = new IvParameterSpec(iv);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(key.toCharArray(), key.getBytes(), 65536, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKeySpec secretKey = new SecretKeySpec(tmp.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
FileInputStream inputStream = new FileInputStream(input);
byte[] inputBytes = new byte[(int) input.length()];
int count;
byte[] outputBytes = cipher.doFinal(inputBytes);
FileOutputStream outputStream = new FileOutputStream(output);
while ((count = inputStream.read(inputBytes, 0, inputBytes.length)) > 0)
{
outputStream.write(inputBytes, 0, count);
}
inputStream.close();
outputStream.close();
}
catch (Exception e)
{
System.out.println("Error while decrypting: " + e.toString());
}
}
What could be the problem?
Thanks in advance!
I'm working on an embedded application, and I need to decrypt a message using PBEKeySpec, since the password is a hash, I don't know if the algorithm is correct, because I always have a return similar to this: '?s.PH ?~+? ?*ol XL >?? ;#??????'
public static String decrypt(String encrypted) throws Exception {
byte[] original = null;
try {
char[] pw = getSecret().toCharArray();
byte[] salt = new byte[]{1, 2, 3, 4, 5, 6, 7, 8};
PBEKeySpec pbeKeySpec = new PBEKeySpec(pw, salt, 1000, 384);
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
SecretKey secretKey = factory.generateSecret(pbeKeySpec);
byte[] key = new byte[32];
byte[] iv = new byte[16];
System.arraycopy(secretKey.getEncoded(), 0, key, 0, 32);
System.arraycopy(secretKey.getEncoded(), 32, iv, 0, 16);
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
original = cipher.doFinal(encrypted.getBytes());
} catch (Exception ex) {
ex.printStackTrace();
}
return new String(original, StandardCharsets.US_ASCII);
}
To generate the password hash:
private static String getSecret() {
StringBuffer hexString = new StringBuffer();
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
byte[] hash = digest.digest(Arrays.copyOf(secret.getBytes(), 36));
for (int i = 0; i < hash.length; i++) {
String hex = Integer.toHexString(0xff & hash[i]);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
} catch (Exception ex) {
Logger.getLogger(CriptografiaHelper.class.getName()).log(Level.SEVERE, null, ex);
}
return hexString.toString();
}
I am getting following error while decrypting.
Once it was working fine but suddenly I am getting this error.
How can I solve this problem?
I have read many articles but couldn't get help.
java.security.InvalidKeyException: Parameters missing
at com.sun.crypto.provider.CipherCore.init(CipherCore.java:388)
at com.sun.crypto.provider.AESCipher.engineInit(AESCipher.java:186)
at javax.crypto.Cipher.implInit(Cipher.java:786)
at javax.crypto.Cipher.chooseProvider(Cipher.java:848)
at javax.crypto.Cipher.init(Cipher.java:1212)
at javax.crypto.Cipher.init(Cipher.java:1152)
at
com.test.security.TestEncryptDecrypt.decrypt(TestEncryptDecrypt.java:92)
at com.test.security.TestEncryptDecrypt.main(TestEncryptDecrypt.java:59)
The code is give below:
public static void main(String []args){
try {
String encString = encrypt("PID=0000000003|ITC=NA|PRN=MNKB0701511135|AMT=1.00|CRN=INR|RU=https://www.testsite.com/testsk/servlet/TestResponseHandler?");
System.out.println("Enc : " + encString);
System.out.println("Dec : "+ decrypt(encString));
} catch (Exception e) {
e.printStackTrace();
}
}
Encrypt method
public static String encrypt(String data) throws Exception {
String keyFile = "E:\\testpath\\Keys\\0000000003.key";
byte[] keyb = Files.readAllBytes(Paths.get(keyFile));
SecretKeySpec skey = new SecretKeySpec(keyb, "AES");
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.ENCRYPT_MODE, skey);
byte[] encVal = c.doFinal(data.getBytes());
return new BASE64Encoder().encode(encVal);
}
Decrypt method
public static String decrypt(String encryptedData)
throws InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, NoSuchAlgorithmException,
NoSuchPaddingException, IOException {
String keyFile = "E:\\testpath\\Keys\\0000000003.key";
byte[] keyb = Files.readAllBytes(Paths.get(keyFile));
SecretKeySpec skey = new SecretKeySpec(keyb, "AES");
Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE, skey);
byte[] decordedValue = Base64.decodeBase64(encryptedData.getBytes());
byte[] decValue = c.doFinal(decordedValue);
return new String(decValue);
}
As the error message says, you are missing a parameter in the init methods. If you're using CBC you should also specify the AlgorithmParameterSpec.
Could you perhaps try the following:
byte[] paramSpecBytes = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
IvParameterSpec paramSpec = new IvParameterSpec(paramSpecBytes);
And in your encrypt and decrypt methods:
c.init(Cipher.ENCRYPT_MODE, skey, paramSpec);
c.init(Cipher.DECRYPT_MODE, skey, paramSpec);
You could fill the bytes with any value you like though, doesn't need to be zero's. Best would be some random value.
I am trying to write an encryption/decryption utility class, but not matter what I do I cannot seem to get decryption working. I keep getting a javax.crypto.BadPaddingException: Given final block not properly padded exception during decryption.
I've looked at a number of examples and other stack overflow questions but can't seem to find my mistake
public class EncryptionUtil {
private static final Log LOGGER = LogFactory.getLog(EncryptionUtil.class);
private static final String CIPHER_MODE = "AES/CBC/PKCS5PADDING";
private static final String CRYPTO_PROPERTIES_PATH = "/crypto.properties";
private static final SecretKeySpec sKey = keySpecFromProperties();
private EncryptionUtil() {}
public static byte[] encrypt(byte[] aBytes) {
try {
SecureRandom lSecureRandom = new SecureRandom();
byte[] ivBytes = new byte[16];
lSecureRandom.nextBytes(ivBytes);
IvParameterSpec lSpec = new IvParameterSpec(ivBytes);
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
cipher.init(Cipher.ENCRYPT_MODE, sKey, lSpec);
byte[] encryptedBytes = cipher.doFinal(aBytes);
byte[] outBytes = new byte[encryptedBytes.length + 16];
System.arraycopy(ivBytes, 0, outBytes, 0, 16);
System.arraycopy(encryptedBytes, 0, outBytes, 16, encryptedBytes.length);
return outBytes;
} catch (Exception aEx) {
LOGGER.error("Failed to encrypt bytes");
throw new RuntimeException(aEx);
}
}
public static byte[] decrypt(byte[] aBytes) {
try {
byte[] lIvBytes = Arrays.copyOfRange(aBytes, aBytes.length - 16, aBytes.length);
byte[] lEncryptedBytes = Arrays.copyOfRange(aBytes, 0, aBytes.length - 16);
IvParameterSpec lIvSpec = new IvParameterSpec(lIvBytes);
Cipher cipher = Cipher.getInstance(CIPHER_MODE);
cipher.init(Cipher.DECRYPT_MODE, sKey, lIvSpec);
return cipher.doFinal(lEncryptedBytes);
}catch (Exception aEx){
LOGGER.error("Failed to decrypt bytes. Returning input bytes", aEx);
return aBytes;
}
}
private static SecretKeySpec keySpecFromProperties(){
try(InputStream lPropStream = EncryptionUtil.class.getResourceAsStream(CRYPTO_PROPERTIES_PATH)){
Properties cryptoProps = new Properties();
cryptoProps.load(lPropStream);
String lSecret = cryptoProps.getProperty("secret");
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(lSecret.getBytes("UTF-8"));
byte[] keyBytes = new byte[16];
System.arraycopy(digest.digest(),0, keyBytes, 0, keyBytes.length);
return new SecretKeySpec(keyBytes, "AES");
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
You prepend your IV to the ciphertext on encryption, but on decryption you copy the last 16 bytes as your IV.
Whatever you do on encryption you must undo on decryption.
I am trying to do AES encryption in j2me.I used almost same code for android and it's working fine there.Following is the block of code. I'm getting null as output
package cartoon;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class MCrypt {
private String iv = "0123456789abcdef";// iv
private IvParameterSpec ivspec;
private SecretKeySpec keyspec;
private Cipher cipher;
private String SecretKey = "fedcba9876543210";// secretKey
public MCrypt() {
ivspec = new IvParameterSpec(iv.getBytes(), 0, iv.getBytes().length);
keyspec = new SecretKeySpec(SecretKey.getBytes(), 0, iv.getBytes().length, "AES");
}
String Decrypt(String text) throws Exception {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] results = null;
int results1 = cipher.doFinal(Base64.decode(text), 0, Base64.decode(text).length, results, 0);
System.out.println("String resultssssssssssssss " + results1);
return new String(results, "UTF-8");
}
String Encrypt(String text)
throws Exception {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
System.out.println("String input : " + text);
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] results = null;
int results1 = cipher.doFinal(text.getBytes(), 0, text.getBytes().length, results, 0);
return Base64.encode(results);
}
}
Printing result
MCrypt mcrypt = new MCrypt();
try {
encrypted = mcrypt.Encrypt("id=450");
decrypted = new String(mcrypt.Decrypt(encrypted));
System.out.println("Encrypted Text : " + encrypted);
System.out.println("Decrypted Text : " + decrypted);
} catch (Exception e) {
e.printStackTrace();
}
Where am I going wrong?
Try the following
You should initialize the byte array first appropriately
String Decrypt(String text) throws Exception {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
// here
byte[] results = cipher.doFinal(Base64.decode(text));
int results1 = cipher.doFinal(Base64.decode(text), 0, Base64.decode(text).length, results, 0);
System.out.println("String resultssssssssssssss " + results1);
return new String(results, "UTF-8");
}
String Encrypt(String text)
throws Exception {
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
System.out.println("String input : " + text);
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
// and here
byte[] results = cipher.doFinal(text.getBytes());
int results1 = cipher.doFinal(text.getBytes(), 0, text.getBytes().length, results, 0);
return Base64.encode(results);
}