I basically need to decrypt a password I retrieve from a server encrypted with Rijndael, I have never worked with encrypting/decrypting before and I am completely lost. I found somewhere in this web that Java has some methods implemented without need of external libraries to do so but I didn't get it. The only thing I need is the decrypt since I won't be writing back into the server anyways.
Any idea on how to do it or where I could find documentation about it?
I don't know if this code, taken from an answer here is what I am looking for, I don't understand much of it, as I said, I've never worked with this kind of stuff before:
byte[] sessionKey = null; //Where you get this from is beyond the scope of this post
byte[] iv = null ; //Ditto
byte[] plaintext = null; //Whatever you want to encrypt/decrypt
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
//You can use ENCRYPT_MODE or DECRYPT_MODE
cipher.calling init(Cipher.ENCRYPT_MODE, new SecretKeySpec(sessionKey, "AES"), new IvParameterSpec(iv));
byte[] ciphertext = cipher.doFinal(plaintext);
Thanks in advance.
Here is a Simple Crypto utility class that might be of help to you. Its based on the code written by ferenc.hechler posted at the following url :
http://www.androidsnippets.com/encryptdecrypt-strings
I have made some changes to it to fit my needs.
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
public class SimpleCrypto {
private static final int KEY_SIZE = 128;
public static String encrypt(String seed, String cleartext) throws NoSuchAlgorithmException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
final byte[] rawKey = getRawKey(seed.getBytes());
final byte[] result = encrypt(rawKey, cleartext.getBytes());
return bin2hex(result);
}
public static String decrypt(String seed, String encrypted) throws NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException {
final byte[] rawKey = getRawKey(seed.getBytes());
final byte[] enc = toByte(encrypted);
final byte[] result = decrypt(rawKey, enc);
return new String(result);
}
public static String decrypt(String seed, byte[] encrypted) throws NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException {
final byte[] rawKey = getRawKey(seed.getBytes());
final byte[] result = decrypt(rawKey, encrypted);
return new String(result);
}
private static byte[] getRawKey(byte[] seed) throws NoSuchAlgorithmException {
final KeyGenerator kgen = KeyGenerator.getInstance("AES");
final SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(seed);
kgen.init(KEY_SIZE, sr); // 192 and 256 bits may not be available
final SecretKey skey = kgen.generateKey();
byte[] raw = skey.getEncoded();
return raw;
}
public static byte[] encrypt(byte[] raw, byte[] clear) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
final SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
final Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
final byte[] encrypted = cipher.doFinal(clear);
return encrypted;
}
public static byte[] decrypt(byte[] raw, byte[] encrypted) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException {
final SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
final Cipher cipher = Cipher.getInstance("AES");
cipher.init(Cipher.DECRYPT_MODE, skeySpec);
final byte[] decrypted = cipher.doFinal(encrypted);
return decrypted;
}
public static String toHex(String txt) {
return bin2hex(txt.getBytes());
}
public static String fromHex(String hex) {
return new String(toByte(hex));
}
public static byte[] toByte(String hexString) {
final int len = hexString.length() / 2;
final byte[] result = new byte[len];
for (int i = 0; i < len; i++) {
result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2), 16).byteValue();
}
return result;
}
public static byte[] getHash(String str) {
MessageDigest digest = null;
try {
digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException ex) {
ex.printStackTrace();
}
digest.reset();
return digest.digest(str.getBytes());
}
static String bin2hex(byte[] data) {
return String.format("%0" + (data.length * 2) + "X", new BigInteger(1, data));
}
}
Here is how you would use it to decrypt something :
final String ssid = "MY_WIFI_SSID";
final String encWifiKey = "myEncryptedWifiKeyString";
String wifiKey = "";
try {
wifiKey = new String(SimpleCrypto.decrypt(SimpleCrypto.getHash(ssid), Base64.decode(encWifiKey, Base64.DEFAULT)));
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
}
Related
I was implementing encryption decryption of a file using the AES/CBC/PKCS5PADDING algorithm. And I noticed some peculiarity. With the correct order of initialization of the IV, everything is decrypted correctly. But if the order is wrong (see commented out lines), the beginning of the line is decoded incorrectly.
But if the decryption happens with wrong IV in CBC mode then nothing should be decrypted. After all, that's how AES/CBC works.
My question is - why is the string still decrypted with the wrong IV ?
Output
org.junit.ComparisonFailure:
Expected :Test string Test string Test string Test string Test string Test string
Actual :�Eݠ�/ՙ�, 9B�� string Test string Test string Test string Test string
Code
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.InvalidParameterSpecException;
import java.security.spec.KeySpec;
public class CryptographyService {
private static final String SECRET_KEY_DERIVATION_ALGORITHM = "PBKDF2WithHmacSHA256";
private static final String CIPHER_ALGORITHM_MODE_PADDING = "AES/CBC/PKCS5PADDING";
private static final String CIPHER_ALGORITHM = "AES";
private static final int SALT_LEN = 32;
private static byte[] createSalt() {
byte[] salt = new byte[SALT_LEN];
SecureRandom random = new SecureRandom();
random.nextBytes(salt);
return salt;
}
private static SecretKey secretKeyCreate(String userPassword, byte[] salt) throws NoSuchAlgorithmException,
InvalidKeySpecException {
SecretKeyFactory factory = SecretKeyFactory.getInstance(SECRET_KEY_DERIVATION_ALGORITHM);
KeySpec spec = new PBEKeySpec(userPassword.toCharArray(), salt, 25000, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), CIPHER_ALGORITHM);
return secret;
}
public static void encrypt(String userPassword, String fileEncryptName, String jsonPasswordsData)
throws NoSuchAlgorithmException, InvalidKeySpecException,
NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IOException {
byte[] salt = createSalt();
SecretKey secretKey = secretKeyCreate(userPassword, salt);
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_MODE_PADDING);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
//cipher.init(Cipher.ENCRYPT_MODE, secretKey); // incorrect decrypt
try (FileOutputStream fileOutputStream = new FileOutputStream(fileEncryptName);
CipherOutputStream cipherOutputStream = new CipherOutputStream(fileOutputStream, cipher)) {
fileOutputStream.write(iv);
fileOutputStream.write(salt);
fileOutputStream.flush();
cipherOutputStream.write(jsonPasswordsData.getBytes(StandardCharsets.UTF_8));
}
}
public static String decrypt(String userPassword, String fileDecryptName) throws NoSuchPaddingException,
NoSuchAlgorithmException, IOException, InvalidParameterSpecException, InvalidKeySpecException,
InvalidAlgorithmParameterException, InvalidKeyException {
Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM_MODE_PADDING);
AlgorithmParameters params = cipher.getParameters();
int ivLength = params.getParameterSpec(IvParameterSpec.class).getIV().length;
byte[] iv = new byte[ivLength];
byte[] salt = new byte[SALT_LEN];
byte[] plainText;
try (FileInputStream fileInputStream = new FileInputStream(fileDecryptName);
CipherInputStream cipherInputStream = new CipherInputStream(fileInputStream, cipher)) {
fileInputStream.read(iv);
fileInputStream.read(salt);
SecretKey secretKey = secretKeyCreate(userPassword, salt);
cipher.init(Cipher.DECRYPT_MODE, secretKey, new IvParameterSpec(iv));
plainText = cipherInputStream.readAllBytes();
}
return new String(plainText, StandardCharsets.UTF_8);
}
}
I am working on a project for my Java programming class to create a password manager, and I am working on encrypting and decrypting my passwords.
I have the encryption piece working fine, but I keep getting an javax.crypto.AEADBadTagException: Tag mismatch! error.
Here is the full error:
Exception in thread "main" javax.crypto.AEADBadTagException: Tag mismatch!
at java.base/com.sun.crypto.provider.GaloisCounterMode.decryptFinal(GaloisCounterMode.java:580)
at java.base/com.sun.crypto.provider.CipherCore.finalNoPadding(CipherCore.java:1116)
at java.base/com.sun.crypto.provider.CipherCore.fillOutputBuffer(CipherCore.java:1053)
at java.base/com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:853)
at java.base/com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:446)
at java.base/javax.crypto.Cipher.doFinal(Cipher.java:2202)
at PasswordVault.Decrypt(PasswordVault.java:89)
at PasswordVault.main(PasswordVault.java:27)
I've been trying to figure out this error on my own through researching here, but I am not having much luck or understanding about what is going wrong.
This is my main class:
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.util.ArrayList;
import java.util.Scanner;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
import java.util.Base64;
public class PasswordVault {
private static ArrayList<Password> passwordVault;
public Scanner keyboard = new Scanner(System.in);
public String website;
public String username;
private String password;
private SecretKey key;
public static void main(String[] args) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, NoSuchProviderException, InvalidAlgorithmParameterException {
passwordVault = new ArrayList<>();
addPassword();
System.out.println(passwordVault);
//byte [] passwordByte = passwordVault.get(0).getPassword().getBytes();
System.out.println(Decrypt(passwordVault.get(0).getPassword(),generateKey()));
}
public static void addPassword() throws NoSuchPaddingException, BadPaddingException, NoSuchAlgorithmException, IllegalBlockSizeException, UnsupportedEncodingException, InvalidKeyException, NoSuchProviderException, InvalidAlgorithmParameterException {
Scanner keyboard = new Scanner(System.in);
String website;
String username;
String password;
SecretKey key = null;
System.out.println("Please enter in the website that you would like to store a password:");
website = keyboard.nextLine();
System.out.println("Please enter your username");
username = keyboard.nextLine();
System.out.println("Please enter your password");
password = keyboard.nextLine();
key = generateKey();
savePassword(website,username,password,key);
}
private static ArrayList<Password>savePassword(String website, String username, String password, SecretKey key) throws IllegalBlockSizeException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, InvalidKeyException, NoSuchProviderException, InvalidAlgorithmParameterException {
String encryptedPassword;
encryptedPassword = Encrypt(password,key);
String stringEncryptedPassword = new String(encryptedPassword);
Password savePass = new Password(website, username, stringEncryptedPassword);
passwordVault.add(savePass);
return passwordVault;
}
public static SecretKey generateKey() throws NoSuchPaddingException, NoSuchAlgorithmException {
SecureRandom random = SecureRandom.getInstanceStrong();
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128, random);
SecretKey key = keyGen.generateKey();
return key;
}
private static String Encrypt(String password, SecretKey key) throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchProviderException {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
byte[] iv = new byte[12];
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(iv);
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte [] bytePassword = password.getBytes("UTF-8");
byte [] encryptedPassword = cipher.doFinal(bytePassword);
/*Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte [] bytePassword = password.getBytes("UTF-8");
byte [] encryptedPassword = cipher.doFinal(bytePassword);
return Base64.getEncoder().encodeToString(encryptedPassword);*/
//return encryptedPassword;
return Base64.getEncoder().encodeToString(encryptedPassword);
}
private static String Decrypt(String password, SecretKey key) throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, NoSuchProviderException, InvalidAlgorithmParameterException {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
byte[] iv = new byte[12];
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(iv);
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
return new String(cipher.doFinal(Base64.getDecoder().decode(password)));
}
//byte [] byteDecryptPassword = cipher.doFinal(password);
// String newPassword = new String(password, "UTF-8");
//Cipher cipher = null;
//cipher = Cipher.getInstance("AES/GCM/NoPadding");
//cipher.init(Cipher.DECRYPT_MODE, key);
/*byte [] bytePassword = new byte[0];
bytePassword = password.getBytes("UTF-8");
byte [] encryptedPassword = new byte[0];
encryptedPassword = cipher.doFinal(bytePassword);*/
}
This is my Password object:
public class Password {
String website;
String login;
String password;
public Password(String website, String login, String password) {
this.website = website;
this.login = login;
this.password = password;
}
public String getWebsite() {
return website;
}
public void setWebsite(String website) {
this.website = website;
}
public String getLogin() {
return login;
}
public void setLogin(String login) {
this.login = login;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
#Override
public String toString(){
return "Website: " + website + " Login: " + login + " Password: " + password;
}
}
What I am hoping to get right now with my tests is a decrypted plain text version of the password that I enter in. Right now, I just keep getting this BadTag issue.
Any help is greatly appreciated.
Just to give you some idea on how you could program this, let's show you a new PasswordVault.
Your own new code fragment also works of course, currently sidesteps the required design for password storage; it is a generic GCM example which doesn't store the IV, doesn't have the vault and so on (which is probably a good idea to start off with if you cannot get GCM to work).
Note that the following code fragment is still not a secure vault, but it shows how to program the fault in an OO-fashion.
import static java.nio.charset.StandardCharsets.UTF_8;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Scanner;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.GCMParameterSpec;
public class PasswordVault {
private static final int KEY_SIZE_BITS = 128;
private static final int GCM_TAG_SIZE_BITS = 128;
private static final int GCM_IV_SIZE_BYTES = 12;
private ArrayList<PasswordEntry> vaultBoxes;
private SecretKey key;
public PasswordVault() throws NoSuchAlgorithmException {
vaultBoxes = new ArrayList<>();
key = generateKey();
}
public void encryptAndStorePasswordEntry(PasswordEntry passwordEntry) throws GeneralSecurityException {
String encryptedPassword = encrypt(passwordEntry.getPassword(), key);
PasswordEntry savePass = new PasswordEntry(passwordEntry.getWebsite(), passwordEntry.getLogin(),
encryptedPassword);
vaultBoxes.add(savePass);
}
public PasswordEntry retrieveAndDecryptPasswordEntry() throws GeneralSecurityException {
// TODO think of a way to retrieve the password for a specific entry
PasswordEntry encryptedPasswordEntry = vaultBoxes.get(0);
String password = decrypt(encryptedPasswordEntry.getPassword(), key);
return new PasswordEntry(encryptedPasswordEntry.getWebsite(), encryptedPasswordEntry.getLogin(), password);
}
public static SecretKey generateKey() throws NoSuchAlgorithmException {
SecureRandom random = SecureRandom.getInstanceStrong();
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(KEY_SIZE_BITS, random);
return keyGen.generateKey();
}
public static String encrypt(String password, SecretKey key) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
byte[] iv = generateRandomIV();
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_SIZE_BITS, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte[] bytePassword = password.getBytes(UTF_8);
byte[] ivCTAndTag = new byte[GCM_IV_SIZE_BYTES + cipher.getOutputSize(bytePassword.length)];
System.arraycopy(iv, 0, ivCTAndTag, 0, GCM_IV_SIZE_BYTES);
cipher.doFinal(bytePassword, 0, bytePassword.length, ivCTAndTag, GCM_IV_SIZE_BYTES);
return Base64.getEncoder().encodeToString(ivCTAndTag);
}
private static byte[] generateRandomIV() {
byte[] iv = new byte[GCM_IV_SIZE_BYTES];
SecureRandom random = new SecureRandom();
random.nextBytes(iv);
return iv;
}
public static String decrypt(String encryptedPassword, SecretKey key) throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
byte[] ivAndCTWithTag = Base64.getDecoder().decode(encryptedPassword);
GCMParameterSpec spec = new GCMParameterSpec(GCM_TAG_SIZE_BITS, ivAndCTWithTag, 0, GCM_IV_SIZE_BYTES);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
byte[] plaintext = cipher.doFinal(ivAndCTWithTag, GCM_IV_SIZE_BYTES, ivAndCTWithTag.length - GCM_IV_SIZE_BYTES);
return new String(plaintext, UTF_8);
}
public static void main(String[] args) throws Exception {
PasswordVault vault = new PasswordVault();
PasswordEntry passwordEntry = readPlainPasswordEntry();
vault.encryptAndStorePasswordEntry(passwordEntry);
System.out.println(vault.vaultBoxes);
PasswordEntry decryptedPasswordEntry = vault.retrieveAndDecryptPasswordEntry();
System.out.println(decryptedPasswordEntry);
}
public static PasswordEntry readPlainPasswordEntry() {
try (Scanner keyboard = new Scanner(System.in)) {
System.out.println("Please enter in the website that you would like to store a password:");
String website = keyboard.nextLine();
System.out.println("Please enter your username");
String login = keyboard.nextLine();
System.out.println("Please enter your password");
String password = keyboard.nextLine();
return new PasswordEntry(website, login, password);
}
}
}
As you will see, I've renamed quite a lot of variables as well and introduced multiple constants. I've made the vault one object with state, which consists of the key and the secure entries.
Of course, in the end you want to serialize the vault to store the encrypted values without the key, which must be stored / retrieved / derived from somewhere else. You don't want to mix retrieving the password and storing the password entries (which I've renamed, because a website and login is not part of a password).
I've also simplified the exception handling and String handling (if you ever perform new String(string) then you might be surprised that it consists of return string; internally). To handle crypto exceptions well, take a look at this answer of mine.
OK, hopefully this helps you along. Good luck with the rest of it.
I actually figured out the solution to my program.
I had to end up refactoring things because I think I kept resetting my iv, which would cause a type mismatch.
Here is my finished and working code:
import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.util.ArrayList;
import java.util.Scanner;
public class TestPasswordVault {
private static ArrayList<Password> passwordVault;
public Scanner keyboard = new Scanner(System.in);
public String website;
public String username;
private String password;
private static SecretKey key;
public static void main(String[] args) throws UnsupportedEncodingException, NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchProviderException {
String test = "kittens";
SecureRandom random = SecureRandom.getInstanceStrong();
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128, random);
SecretKey key = keyGen.generateKey();
byte[] iv = new byte[12];
random.nextBytes(iv);
System.out.println(test);
byte [] newTest = doEncrypt(test,iv,random,key);
System.out.println(newTest);
System.out.println(doDecrypt(newTest,iv,random,key));
}
public static byte [] doEncrypt(String password, byte [] iv, SecureRandom random, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.ENCRYPT_MODE, key, spec);
byte [] encryptPassword = password.getBytes("UTF-8");
byte[] cipherText = cipher.doFinal(encryptPassword);
return cipherText;
}
public static String doDecrypt(byte [] encrypted, byte [] iv, SecureRandom random, SecretKey key)throws NoSuchPaddingException, NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding", "SunJCE");
GCMParameterSpec spec = new GCMParameterSpec(128, iv);
cipher.init(Cipher.DECRYPT_MODE, key, spec);
byte[] plainText = cipher.doFinal(encrypted);
return new String(plainText);
}
}
this code encryption/decryption dynamic data that entered by user:
private final String characterEncoding = "UTF-8";
private final String cipherTransformation = "AES/CBC/PKCS5Padding";
private final String aesEncryptionAlgorithm = "AES";
public String encrypt(String plainText, String key) throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException{
byte[] plainTextbytes = plainText.getBytes(characterEncoding);
byte[] keyBytes = getKeyBytes(key);
return Base64.encodeToString(encrypt(plainTextbytes,keyBytes, keyBytes), Base64.DEFAULT);
}
public String decrypt(String encryptedText, String key) throws KeyException, GeneralSecurityException, GeneralSecurityException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, IOException {
byte[] cipheredBytes = Base64.decode(encryptedText, Base64.DEFAULT);
byte[] keyBytes = getKeyBytes(key);
return new String(decrypt(cipheredBytes, keyBytes, keyBytes), characterEncoding);
}
public byte[] decrypt(byte[] cipherText, byte[] key, byte [] initialVector) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException, InvalidParameterSpecException {
Cipher cipher = Cipher.getInstance(cipherTransformation);
SecretKeySpec secretKeySpecy = new SecretKeySpec(key, aesEncryptionAlgorithm);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpecy, ivParameterSpec);
cipherText = cipher.doFinal(cipherText);
return cipherText;
}
public byte[] encrypt(byte[] plainText, byte[] key, byte [] initialVector) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidAlgorithmParameterException, IllegalBlockSizeException, BadPaddingException
{
Cipher cipher = Cipher.getInstance(cipherTransformation);
SecretKeySpec secretKeySpec = new SecretKeySpec(key, aesEncryptionAlgorithm);
IvParameterSpec ivParameterSpec = new IvParameterSpec(initialVector);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
plainText = cipher.doFinal(plainText);
return plainText;
}
private byte[] getKeyBytes(String key) throws UnsupportedEncodingException{
byte[] keyBytes= new byte[16];
byte[] parameterKeyBytes= key.getBytes(characterEncoding);
System.arraycopy(parameterKeyBytes, 0, keyBytes, 0, Math.min(parameterKeyBytes.length, keyBytes.length));
return keyBytes;
}
but for some data (example : u8/OgSllm2agXlDrGcdqWg== ) decryption is not working and execution catch:
javax.crypto.BadPaddingException: error:06065064:digital envelope routines:EVP_DecryptFinal_ex:bad decrypt
or for some data get different error , example : SmQ0YMiq+SHn34m8h3gWw==
get this error :
java.lang.IllegalArgumentException: bad base-64
Try with this code and download library commons-codec-1.11-bin from the below link and add it to build path
enter link description here
Java Code:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class AES {
public static String encrypt(String key, String initVector, String value) {
try {
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);
byte[] encrypted = cipher.doFinal(value.getBytes());
System.out.println("encrypted string: "
+ Base64.encodeBase64String(encrypted));
return Base64.encodeBase64String(encrypted);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static String decrypt(String key, String initVector, String encrypted) {
try {
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.DECRYPT_MODE, skeySpec, iv);
byte[] original = cipher.doFinal(Base64.decodeBase64(encrypted));
return new String(original);
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
public static void main(String[] args) {
String key = "Bar12345Bar12345"; // 128 bit key
String initVector = "RandomInitVector"; // 16 bytes IV
System.out.println(decrypt(key, initVector,
encrypt(key, initVector, "Hello World")));
}
}
I convert the secretkey into bytes with following code
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
byte[] bkey=key.getEncoded();
Now how do I get the key from bkey? I tried:
SecretKeySpec secretkey = new SecretKeySpec(bkey,"DES");
SecretKeyFactory sfkey = SecretKeyFactory.getInstance("DES");
SecretKey skey = sfkey.generateSecret(secretkey);
I get the following error:
Error during Exception java.security.spec.InvalidKeySpecException: Inappropriate key specification
This should work
SecretKey key = KeyGenerator.getInstance("DES").generateKey();
byte[] data = key.getEncoded();
SecretKey key2 = new SecretKeySpec(data, 0, data.length, "DES");
Try some of this code...
import javax.crypto.Cipher;
import javax.crypto.BadPaddingException;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.InvalidKeyException;
public class DESede {
private static String algorithm = "DESede";
private static Key key = null;
private static SecretKey secretKey = null;
private static Cipher cipher = null;
private static DESede obj = new DESede();
private DESede() {
try {
key = KeyGenerator.getInstance(algorithm).generateKey();
KeyGenerator.getInstance(algorithm).getProvider();
byte[] keyBytes = key.getEncoded();
String keyFormat = key.getFormat();
String keyAlgorithm = key.getAlgorithm();
String keyString = new String(keyBytes);
System.out.println("Key Format::" + keyFormat);
System.out.println("Key Algorithm::" + keyAlgorithm);
System.out.println("Key String::" + keyString);
keyString.getBytes();
secretKey = new SecretKeySpec(keyBytes, 0, keyBytes.length, "DESede");
byte[] secretKeyBytes = key.getEncoded();
String secretKeyFormat = key.getFormat();
String secretKeyAlgorithm = key.getAlgorithm();
String secretKeyString = new String(secretKeyBytes);
System.out.println("Secret Key Format::" + secretKeyFormat);
System.out.println("Secret Key Algorithm::" + secretKeyAlgorithm);
System.out.println("Secret Key String::" + secretKeyString);
String keyNewString = "bXŒ*êÂÕê›æOÄ’Îý‘ãô|8¶Ë1";
byte[] keyNewBytes = keyString.getBytes();
secretKey = new SecretKeySpec(keyBytes, 0, keyBytes.length, "DESede");
cipher = Cipher.getInstance(algorithm);
} catch (Exception e) {
}
}
public static DESede getInstance() {
return obj;
}
public static byte[] encrypt(String input) throws InvalidKeyException,
BadPaddingException, IllegalBlockSizeException {
System.out.println("Inside encrypt()");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] inputBytes = input.getBytes();
System.out.println("Exit encrypt()");
return cipher.doFinal(inputBytes);
}
public static String decrypt(byte[] encryptionBytes)
throws InvalidKeyException, BadPaddingException,
IllegalBlockSizeException {
System.out.println("Inside decrypt()");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] recoveredBytes = cipher.doFinal(encryptionBytes);
String recovered = new String(recoveredBytes);
System.out.println("Exiting decrypt()");
return recovered;
}
public static void main(String args[]) throws InvalidKeyException,
BadPaddingException, IllegalBlockSizeException {
byte[] encryptedValue = DESede.encrypt("plz try encrypt and decrypt me");
System.out.println("encryptedValue::" + encryptedValue);
String decryptedValue = DESede.decrypt(encryptedValue);
System.out.println("decryptedValue::" + decryptedValue);
}
}
Every method I write to encode a string in Java using 3DES can't be decrypted back to the original string. Does anyone have a simple code snippet that can just encode and then decode the string back to the original string?
I know I'm making a very silly mistake somewhere in this code. Here's what I've been working with so far:
** note, I am not returning the BASE64 text from the encrypt method, and I am not base64 un-encoding in the decrypt method because I was trying to see if I was making a mistake in the BASE64 part of the puzzle.
public class TripleDESTest {
public static void main(String[] args) {
String text = "kyle boon";
byte[] codedtext = new TripleDESTest().encrypt(text);
String decodedtext = new TripleDESTest().decrypt(codedtext);
System.out.println(codedtext);
System.out.println(decodedtext);
}
public byte[] encrypt(String message) {
try {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("HG58YZ3CR9".getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;)
{
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] plainTextBytes = message.getBytes("utf-8");
final byte[] cipherText = cipher.doFinal(plainTextBytes);
final String encodedCipherText = new sun.misc.BASE64Encoder().encode(cipherText);
return cipherText;
}
catch (java.security.InvalidAlgorithmParameterException e) { System.out.println("Invalid Algorithm"); }
catch (javax.crypto.NoSuchPaddingException e) { System.out.println("No Such Padding"); }
catch (java.security.NoSuchAlgorithmException e) { System.out.println("No Such Algorithm"); }
catch (java.security.InvalidKeyException e) { System.out.println("Invalid Key"); }
catch (BadPaddingException e) { System.out.println("Invalid Key");}
catch (IllegalBlockSizeException e) { System.out.println("Invalid Key");}
catch (UnsupportedEncodingException e) { System.out.println("Invalid Key");}
return null;
}
public String decrypt(byte[] message) {
try
{
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("HG58YZ3CR9".getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;)
{
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
//final byte[] encData = new sun.misc.BASE64Decoder().decodeBuffer(message);
final byte[] plainText = decipher.doFinal(message);
return plainText.toString();
}
catch (java.security.InvalidAlgorithmParameterException e) { System.out.println("Invalid Algorithm"); }
catch (javax.crypto.NoSuchPaddingException e) { System.out.println("No Such Padding"); }
catch (java.security.NoSuchAlgorithmException e) { System.out.println("No Such Algorithm"); }
catch (java.security.InvalidKeyException e) { System.out.println("Invalid Key"); }
catch (BadPaddingException e) { System.out.println("Invalid Key");}
catch (IllegalBlockSizeException e) { System.out.println("Invalid Key");}
catch (UnsupportedEncodingException e) { System.out.println("Invalid Key");}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Your code was fine except for the Base 64 encoding bit (which you mentioned was a test), the reason the output may not have made sense is that you were displaying a raw byte array (doing toString() on a byte array returns its internal Java reference, not the String representation of the contents). Here's a version that's just a teeny bit cleaned up and which prints "kyle boon" as the decoded string:
import java.security.MessageDigest;
import java.util.Arrays;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class TripleDESTest {
public static void main(String[] args) throws Exception {
String text = "kyle boon";
byte[] codedtext = new TripleDESTest().encrypt(text);
String decodedtext = new TripleDESTest().decrypt(codedtext);
System.out.println(codedtext); // this is a byte array, you'll just see a reference to an array
System.out.println(decodedtext); // This correctly shows "kyle boon"
}
public byte[] encrypt(String message) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("HG58YZ3CR9"
.getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher cipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, iv);
final byte[] plainTextBytes = message.getBytes("utf-8");
final byte[] cipherText = cipher.doFinal(plainTextBytes);
// final String encodedCipherText = new sun.misc.BASE64Encoder()
// .encode(cipherText);
return cipherText;
}
public String decrypt(byte[] message) throws Exception {
final MessageDigest md = MessageDigest.getInstance("md5");
final byte[] digestOfPassword = md.digest("HG58YZ3CR9"
.getBytes("utf-8"));
final byte[] keyBytes = Arrays.copyOf(digestOfPassword, 24);
for (int j = 0, k = 16; j < 8;) {
keyBytes[k++] = keyBytes[j++];
}
final SecretKey key = new SecretKeySpec(keyBytes, "DESede");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
final Cipher decipher = Cipher.getInstance("DESede/CBC/PKCS5Padding");
decipher.init(Cipher.DECRYPT_MODE, key, iv);
// final byte[] encData = new
// sun.misc.BASE64Decoder().decodeBuffer(message);
final byte[] plainText = decipher.doFinal(message);
return new String(plainText, "UTF-8");
}
}
Here is a solution using the javax.crypto library and the apache commons codec library for encoding and decoding in Base64:
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import org.apache.commons.codec.binary.Base64;
public class TrippleDes {
private static final String UNICODE_FORMAT = "UTF8";
public static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
private KeySpec ks;
private SecretKeyFactory skf;
private Cipher cipher;
byte[] arrayBytes;
private String myEncryptionKey;
private String myEncryptionScheme;
SecretKey key;
public TrippleDes() throws Exception {
myEncryptionKey = "ThisIsSpartaThisIsSparta";
myEncryptionScheme = DESEDE_ENCRYPTION_SCHEME;
arrayBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
ks = new DESedeKeySpec(arrayBytes);
skf = SecretKeyFactory.getInstance(myEncryptionScheme);
cipher = Cipher.getInstance(myEncryptionScheme);
key = skf.generateSecret(ks);
}
public String encrypt(String unencryptedString) {
String encryptedString = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
byte[] encryptedText = cipher.doFinal(plainText);
encryptedString = new String(Base64.encodeBase64(encryptedText));
} catch (Exception e) {
e.printStackTrace();
}
return encryptedString;
}
public String decrypt(String encryptedString) {
String decryptedText=null;
try {
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedText = Base64.decodeBase64(encryptedString);
byte[] plainText = cipher.doFinal(encryptedText);
decryptedText= new String(plainText);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedText;
}
public static void main(String args []) throws Exception
{
TrippleDes td= new TrippleDes();
String target="imparator";
String encrypted=td.encrypt(target);
String decrypted=td.decrypt(encrypted);
System.out.println("String To Encrypt: "+ target);
System.out.println("Encrypted String:" + encrypted);
System.out.println("Decrypted String:" + decrypted);
}
}
Running the above program results with the following output:
String To Encrypt: imparator
Encrypted String:FdBNaYWfjpWN9eYghMpbRA==
Decrypted String:imparator
I had hard times figuring it out myself and this post helped me to find the right answer for my case. When working with financial messaging as ISO-8583 the 3DES requirements are quite specific, so for my especial case the "DESede/CBC/PKCS5Padding" combinations wasn't solving the problem. After some comparative testing of my results against some 3DES calculators designed for the financial world I found the the value "DESede/ECB/Nopadding" is more suited for the the specific task.
Here is a demo implementation of my TripleDes class (using the Bouncy Castle provider)
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
*
* #author Jose Luis Montes de Oca
*/
public class TripleDesCipher {
private static String TRIPLE_DES_TRANSFORMATION = "DESede/ECB/Nopadding";
private static String ALGORITHM = "DESede";
private static String BOUNCY_CASTLE_PROVIDER = "BC";
private Cipher encrypter;
private Cipher decrypter;
public TripleDesCipher(byte[] key) throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
InvalidKeyException {
Security.addProvider(new BouncyCastleProvider());
SecretKey keySpec = new SecretKeySpec(key, ALGORITHM);
encrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER);
encrypter.init(Cipher.ENCRYPT_MODE, keySpec);
decrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION, BOUNCY_CASTLE_PROVIDER);
decrypter.init(Cipher.DECRYPT_MODE, keySpec);
}
public byte[] encode(byte[] input) throws IllegalBlockSizeException, BadPaddingException {
return encrypter.doFinal(input);
}
public byte[] decode(byte[] input) throws IllegalBlockSizeException, BadPaddingException {
return decrypter.doFinal(input);
}
}
Here's a very simply static encrypt/decrypt class biased on the Bouncy Castle no padding example by Jose Luis Montes de Oca. This one is using "DESede/ECB/PKCS7Padding" so I don't have to bother manually padding.
package com.zenimax.encryption;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.Security;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
*
* #author Matthew H. Wagner
*/
public class TripleDesBouncyCastle {
private static String TRIPLE_DES_TRANSFORMATION = "DESede/ECB/PKCS7Padding";
private static String ALGORITHM = "DESede";
private static String BOUNCY_CASTLE_PROVIDER = "BC";
private static void init()
{
Security.addProvider(new BouncyCastleProvider());
}
public static byte[] encode(byte[] input, byte[] key)
throws IllegalBlockSizeException, BadPaddingException,
NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, InvalidKeyException {
init();
SecretKey keySpec = new SecretKeySpec(key, ALGORITHM);
Cipher encrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION,
BOUNCY_CASTLE_PROVIDER);
encrypter.init(Cipher.ENCRYPT_MODE, keySpec);
return encrypter.doFinal(input);
}
public static byte[] decode(byte[] input, byte[] key)
throws IllegalBlockSizeException, BadPaddingException,
NoSuchAlgorithmException, NoSuchProviderException,
NoSuchPaddingException, InvalidKeyException {
init();
SecretKey keySpec = new SecretKeySpec(key, ALGORITHM);
Cipher decrypter = Cipher.getInstance(TRIPLE_DES_TRANSFORMATION,
BOUNCY_CASTLE_PROVIDER);
decrypter.init(Cipher.DECRYPT_MODE, keySpec);
return decrypter.doFinal(input);
}
}
private static final String UNICODE_FORMAT = "UTF8";
private static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
private KeySpec ks;
private SecretKeyFactory skf;
private Cipher cipher;
byte[] arrayBytes;
private String encryptionSecretKey = "ThisIsSpartaThisIsSparta";
SecretKey key;
public TripleDesEncryptDecrypt() throws Exception {
convertStringToSecretKey(encryptionSecretKey);
}
public TripleDesEncryptDecrypt(String encryptionSecretKey) throws Exception {
convertStringToSecretKey(encryptionSecretKey);
}
public SecretKey convertStringToSecretKey (String encryptionSecretKey) throws Exception {
arrayBytes = encryptionSecretKey.getBytes(UNICODE_FORMAT);
ks = new DESedeKeySpec(arrayBytes);
skf = SecretKeyFactory.getInstance(DESEDE_ENCRYPTION_SCHEME);
cipher = Cipher.getInstance(DESEDE_ENCRYPTION_SCHEME);
key = skf.generateSecret(ks);
return key;
}
/**
* Encrypt without specifying secret key
*
* #param unencryptedString
* #return String
*/
public String encrypt(String unencryptedString) {
String encryptedString = null;
try {
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
byte[] encryptedText = cipher.doFinal(plainText);
encryptedString = new String(Base64.encodeBase64(encryptedText));
} catch (Exception e) {
e.printStackTrace();
}
return encryptedString;
}
/**
* Encrypt with specified secret key
*
* #param unencryptedString
* #return String
*/
public String encrypt(String encryptionSecretKey, String unencryptedString) {
String encryptedString = null;
try {
key = convertStringToSecretKey(encryptionSecretKey);
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] plainText = unencryptedString.getBytes(UNICODE_FORMAT);
byte[] encryptedText = cipher.doFinal(plainText);
encryptedString = new String(Base64.encodeBase64(encryptedText));
} catch (Exception e) {
e.printStackTrace();
}
return encryptedString;
}
/**
* Decrypt without specifying secret key
* #param encryptedString
* #return
*/
public String decrypt(String encryptedString) {
String decryptedText=null;
try {
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedText = Base64.decodeBase64(encryptedString);
byte[] plainText = cipher.doFinal(encryptedText);
decryptedText= new String(plainText);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedText;
}
/**
* Decrypt with specified secret key
* #param encryptedString
* #return
*/
public String decrypt(String encryptionSecretKey, String encryptedString) {
String decryptedText=null;
try {
key = convertStringToSecretKey(encryptionSecretKey);
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedText = Base64.decodeBase64(encryptedString);
byte[] plainText = cipher.doFinal(encryptedText);
decryptedText= new String(plainText);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedText;
}
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.Key;
import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import javax.crypto.spec.IvParameterSpec;
import java.util.Base64;
import java.util.Base64.Encoder;
/**
*
* #author shivshankar pal
*
* this code is working properly. doing proper encription and decription
note:- it will work only with jdk8
*
*
*/
public class TDes {
private static byte[] key = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02,
0x02, 0x02, 0x02, 0x02, 0x02, 0x02 };
private static byte[] keyiv = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00 };
public static String encode(String args) {
System.out.println("plain data==> " + args);
byte[] encoding;
try {
encoding = Base64.getEncoder().encode(args.getBytes("UTF-8"));
System.out.println("Base64.encodeBase64==>" + new String(encoding));
byte[] str5 = des3EncodeCBC(key, keyiv, encoding);
System.out.println("des3EncodeCBC==> " + new String(str5));
byte[] encoding1 = Base64.getEncoder().encode(str5);
System.out.println("Base64.encodeBase64==> " + new String(encoding1));
return new String(encoding1);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public static String decode(String args) {
try {
System.out.println("encrypted data==>" + new String(args.getBytes("UTF-8")));
byte[] decode = Base64.getDecoder().decode(args.getBytes("UTF-8"));
System.out.println("Base64.decodeBase64(main encription)==>" + new String(decode));
byte[] str6 = des3DecodeCBC(key, keyiv, decode);
System.out.println("des3DecodeCBC==>" + new String(str6));
String data=new String(str6);
byte[] decode1 = Base64.getDecoder().decode(data.trim().getBytes("UTF-8"));
System.out.println("plaintext==> " + new String(decode1));
return new String(decode1);
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return "u mistaken in try block";
}
private static byte[] des3EncodeCBC(byte[] key, byte[] keyiv, byte[] data) {
try {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("desede/ CBC/PKCS5Padding");
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
byte[] bout = cipher.doFinal(data);
return bout;
} catch (Exception e) {
System.out.println("methods qualified name" + e);
}
return null;
}
private static byte[] des3DecodeCBC(byte[] key, byte[] keyiv, byte[] data) {
try {
Key deskey = null;
DESedeKeySpec spec = new DESedeKeySpec(key);
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("desede/ CBC/NoPadding");//PKCS5Padding NoPadding
IvParameterSpec ips = new IvParameterSpec(keyiv);
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] bout = cipher.doFinal(data);
return bout;
} catch (Exception e) {
System.out.println("methods qualified name" + e);
}
return null;
}
}