turning my AES 128 to AES 256 - java

I copied this code from here and modified it, but then as I've read along AES I've noticed that this is using 128 since the number of key characters are only 16, now how do I make it so that it will be AES 256, though I've also read somewhere that java does not primarily allow AES 256 and only limits to AES 128, and that you need to do some more configuration for it to happen, but I am not that sure if what he said there was true and if how do I proceed with those changes. This is also my first time handling AES.
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
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.codec.binary.Base64;
public class AES {
private static SecretKeySpec secretKey ;
private static byte[] key ;
private static String decryptedString;
private static String encryptedString;
public static void setKey(String myKey){
MessageDigest sha = null;
try {
key = myKey.getBytes("UTF-8");
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only first 128 bit
// System.out.println(new String(key,"UTF-8"));
secretKey = new SecretKeySpec(key, "AES");
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
}
}
public static String getDecryptedString() {
return decryptedString;
}
public static void setDecryptedString(String decryptedString) {
AES.decryptedString = decryptedString;
}
public static String getEncryptedString() {
return encryptedString;
}
public static void setEncryptedString(String encryptedString) {
AES.encryptedString = encryptedString;
}
public static String encrypt(String initVector, String strToEncrypt) throws InvalidAlgorithmParameterException
{
try
{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
setEncryptedString(Base64.encodeBase64String(cipher.doFinal(strToEncrypt.getBytes("UTF-8"))));
}
catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException e)
{
System.out.println("Error while encrypting: "+e.toString());
}
return null;
}
public static String decrypt(String initVector, String strToDecrypt) throws InvalidAlgorithmParameterException, UnsupportedEncodingException
{
try
{
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
IvParameterSpec iv = new IvParameterSpec(initVector.getBytes("UTF-8"));
cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
setDecryptedString(new String(cipher.doFinal(Base64.decodeBase64(strToDecrypt))));
}
catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e)
{
System.out.println("Error while decrypting: "+e.toString());
}
return null;
}
public static void main(String args[]) throws InvalidAlgorithmParameterException, UnsupportedEncodingException
{
String initVector = "Bw/+ctBXLE4=#f9t"; // 16 bytes IV
final String strToEncrypt = "12345657";
final String strPssword = "ViK##Uef$#!BZFgAUW6qZiudgoQ==";
AES.setKey(strPssword);
AES.encrypt(initVector, strToEncrypt.trim());
System.out.println("String to Encrypt: " + strToEncrypt);
System.out.println("Encrypted: " + AES.getEncryptedString());
final String strToDecrypt = AES.getEncryptedString();
AES.decrypt(initVector, strToDecrypt.trim());
System.out.println("String To Decrypt : " + strToDecrypt);
System.out.println("Decrypted : " + AES.getDecryptedString());
}
}

Related

Encrypt a field to send to another API

I have a request where there is a field "number_token" that I need to encrypt to send to another API to validate. What is the best method to do this?
Example:
"number_token":"123456789"
encrypt:
"number_token":"iIsInN1YieyJpc3MiOiJHZXR3YXk.gcGFnQmFuayBQQI6ImIyYzMxMTlmLWU3ZjktNDZjZS05NTMxLTkyMTNlNWRjNWNiMSIsImlhdCI6MTY1OTgyNjUyOCwiZXhwIjoxNjU5ODI2NzA4fQ.mL-jivitV30N1PLq10CmI4ZWxCcBivGf5QGVus7Vsyw"
There are many factors to be considered but to get started you can use below logic to encrypt. Credits https://www.javaguides.net/2020/02/java-string-encryption-decryption-example.html?m=1
Here is the complete Java program to encrypt and decrypt string or text in Java:
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class AESEncryptionDecryption {
private static SecretKeySpec secretKey;
private static byte[] key;
private static final String ALGORITHM = "AES";
public void prepareSecreteKey(String myKey) {
MessageDigest sha = null;
try {
key = myKey.getBytes(StandardCharsets.UTF_8);
sha = MessageDigest.getInstance("SHA-1");
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, ALGORITHM);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
public String encrypt(String strToEncrypt, String secret) {
try {
prepareSecreteKey(secret);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
} catch (Exception e) {
System.out.println("Error while encrypting: " + e.toString());
}
return null;
}
public String decrypt(String strToDecrypt, String secret) {
try {
prepareSecreteKey(secret);
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
} catch (Exception e) {
System.out.println("Error while decrypting: " + e.toString());
}
return null;
}
public static void main(String[] args) {
final String secretKey = "secrete";
String originalString = "javaguides";
AESEncryptionDecryption aesEncryptionDecryption = new AESEncryptionDecryption();
String encryptedString = aesEncryptionDecryption.encrypt(originalString, secretKey);
String decryptedString = aesEncryptionDecryption.decrypt(encryptedString, secretKey);
System.out.println(originalString);
System.out.println(encryptedString);
System.out.println(decryptedString);
}
}

Spring, how to encode and decode a String

I am trying to encode a String so I can store it safely in my database. Most password encoders, like bcrypt, can only hash your String, with no way of getting it back (which for a password makes sense), and I want to decode it when I retrieve the information from my database.
I tried using org.springframework.security.crypto.encrypt.Encryptors.queryableText() but the method is deprecated.
Is there any other way to do it?
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class CryptoManager {
//Key for encryption and decryption
public static final byte[] KEY =
{118, 106, 107, 122, 76, 99, 69, 83, 101, 103, 82, 101, 116, 75, 101, 127};
public static void main(String args[]) {
String salt = "HELLO";
String encryptedString = encrypt(salt, "HelloWorld12345");
System.out.println("Encripted string is " + encryptedString);
String decryptedString = decrypt(salt, encryptedString);
System.out.println("Decrypted string is " + decryptedString);
}
public static String encrypt(String salt, String plainText) {
if (plainText == null || plainText.isEmpty()) {
System.out.println("No data to encrypt!");
return plainText;
}
Cipher cipher = null;
String encryptedString = "";
try {
// Creating a Cipher object
cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
// Creating a secret key from KEY byte array
final SecretKeySpec secretKey = new SecretKeySpec(KEY, "AES");
// Initializing a Cipher object
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
// Encrypting the plain text string
byte[] encryptedText = cipher.doFinal(salt.concat(plainText).getBytes());
// Encoding the encrypted text to Base64
encryptedString = Base64.getEncoder().encodeToString(encryptedText);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException
| IllegalBlockSizeException | BadPaddingException ex) {
System.out.println("Exception caught while encrypting : " + ex);
}
return encryptedString;
}
public static String decrypt(String salt, String cipherText) {
if (cipherText == null || cipherText.isEmpty()) {
System.out.println("No data to decrypt!");
return cipherText;
}
String decryptedString = "";
Cipher cipher = null;
try {
// Creating a Cipher object
cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
// Creating a secret key from KEY byte array
final SecretKeySpec secretKey = new SecretKeySpec(KEY, "AES");
// Initializing a Cipher object
cipher.init(Cipher.DECRYPT_MODE, secretKey);
// Decoding from Base64
byte[] encryptedText = Base64.getDecoder().decode(cipherText.getBytes());
// Decrypting to plain text
decryptedString = new String(cipher.doFinal(encryptedText));
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeyException
| IllegalBlockSizeException | BadPaddingException ex) {
System.out.println("Exception caught while decrypting : " + ex);
}
return decryptedString.replace(salt, "");
}
}
Check this out for more detail
Since you want to store the data securely in database, what you really need to do is encrypt the data before writing to database from application.
To encrypt/decrypt the data from application you can use Symmetric key algorithm like AES.
To automatically convert this in entity you can add a converter in corresponding column
#Convert(converter = DataEncryptDecryptConverter.class)
#Column(name = "DATA")
private String data;
And the converter
#Converter
#Component
public class DataEncryptDecryptConverter implements AttributeConverter<String, String> {
#Override
public String convertToDatabaseColumn(String attribute) {
// Code to encrypt data
}
#Override
public String convertToEntityAttribute(String dbData) {
// Code to decrypt data
}
}

InvalidKeyException DER input not a bit string

import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Arrays;
import javax.crypto.Cipher;
import org.apache.commons.codec.binary.Base64;
public class DJExampleDecryptCode
{
public static void main(String[] args)
{
try
{
String encryptedText = "q3sEN1NZZyseoFy9H3WIwNf9jpGrDTTqh/AticRV2pnb1KZ5lieuK5jw3JgctgYUnTE03xnMcOL50UGKZ4dbYEt5XGCZyNVgh1qVGF7Vgnvi5PKndnpKLcoSUJCcbu/lyLI2P+Zd7ZH0/tRKRn1zqrPAWUH3VjtUt7qkIcdIYyaoHP5I7eiZRk6FL9ugUQJnz8WFgM4mcRJ5Zs/NLdaXKeHMO4nPQBTOLNaPdNxW2MM+qlv0HN/fs4rPMRGUw0xXhjWsmSNqadASfn7UX4fL79CmGyKfm8ol4njZakZbsfes/zstc5Su0swycfFSkjXAjPjvMGdBs5/HSLXYAvQPoA==";
String TextToEncrypt = "Test";
String decryptedString = decrypt(encryptedText);
String encryptedString = encrypt(TextToEncrypt);
//Printing
System.out.println("Decrypted Text: " + decryptedString);
System.out.println("Encrypted Text: " + encryptedString);
}
catch (Exception e)
{
e.printStackTrace();
}
}
//public static String decrypt(String text, String privateKeyString) throws GeneralSecurityException
public static String decrypt(String text) throws GeneralSecurityException
{
String DJPrivateKey = ".....";
PrivateKey privateKey = stringToPrivateKey(DJPrivateKey);
byte[] dectyptedText = null;
try
{
final Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
dectyptedText = cipher.doFinal(base64Decode(text));
}
catch (Exception ex)
{
ex.printStackTrace();
}
return new String(dectyptedText);
}
public static String encrypt(String data) throws GeneralSecurityException
{
String PCMSPublicKey = "MIIFDjBABgkqhkiG9w0BBQ0wMzAbBgkqhkiG9w0BBQwwDgQIV/0v/U5+6pgCAggAMBQGCCqGSIb3DQMHBAhSuqMZCoVAxgSCBMhKaVDCjOS9q0jEc+nUCEKQD73pHte/9nMdTkHbFGpu+1amzpY0YLhgqVTQhDp43amH6IvM3KfmM+9M5i0bXBksa+5la2kVl8Ntw6fzc1xFtcSMLb8CFkk0gV3l6kcKEo1rN2TiH3jGQz43DFHUJbnITWwY3SFCsWPZF2oegTAMSEKhOJ6h9bad3KoqNmqji6hdk9ONhQBarDrZGL9l+8GWnx9TyVxAVltBxzv0DRlqXlKhVkfV2XqkiECcilFHeoaI+cV6W1z8S9kFPdnm93QjCu88l1lG1a5ox4tu4dPHj4u7uVZKuEBkpr7HpF0uL+o+JEflNjUl/BYlS3++l6lfRpOp6mb2VVt1zQgoKVR1wZZeSoEqhJ/r75Krybq4TdXXqs4IdPZmSwIPTVM8n5ZvzUz/F+K46rYIQchz3GPCpKEPI/9+OhqUKtXe2KpPsZtD7hJ7+r1g99MwzEjyET6l7lLuIE2SpKS0wxZB5qb0+92+SfyPwQWIM5tfv1Gs7M8A2MFz9GclXsaGpt+mx0DQPiMkpdoB9e5GbO1PGlP3MWhUmQ6wwIUVVjGryJuvLFL+4psDeUzkdKilG9nPDVSWHLlCx1C3k8hcuJUy1bTihrFprcOEjuzGzmhp3IUQc+5Z4dydM/2AmYFCNmjySRKYZVRBPfPrcVfDo8P1lzlYeXLcWubMlwxyRfv/WjzJkyMlDSiYEEnkcYJrCgeocsU8qJ+yq1QAsTs361Svi2tQ7lJZjp1FtIdvMr+U32eW1Pri+vn4LWdPcPzxbrLHN/daV+l3Ttw493x0R7WMDnhcS8yhd8NlWoh43IzmQDCn33Lek7WS3HmSzTAg6bfxmYZf9Ogn86DR/q2c2ZKwbs3nloHdfkKklOOqgRPic7nP8khsd+pjTULZUDmKa3d0OW8Ps5fTY/GzWrJBLVEoM8bN0w3CUsHixSQOh1pMwJUiyAT/cJPZfru1gtUeNkSJ5u/atc6HaPc6sfrhLF6RWyhIYKyqoM2dyLFC3hi+N0ZLBZwp/tnIou24dtwlJnLvKCinzO0pUTJC2yOwsnfL57h+ikdd3xS9fMWwpiSdNps086japrp12GU9VyBZX8b9QEip/Hxw778OK1x853+WYM978wNPrFwIfWtQpvNZMi8Mt0WXDvfHiG8JK9PKDoS25iV8SrwZScfBTMIi95j419BuhcVca1fi0keEEKaqMzBus4Mgz421Qcy0xv2u81w90qoMyXBwadRODtrJBQIovHBCKVRkxEm64Rr3fCWGjralnKcjxDKa77qakFlFOyNJsplnlC0mc229E19JXlxpcdDlivscE727KLLYu8rPUEWMZY/PA0D9JH+u+52A81ur0vuCnTLF1V0WG8ECJwgVTbIfByPoi+MKuvmW1pvixwBXiIh7as95gVl47HAXmCYOj0bnD0yO/pFSLoiAURl0j2R/c/NtKjz5TQ9F3O3U83UojatwtIyc7xN6Bs+iwTPaBOJrI6Sbgc5yDJPFczhPQDSpFZVtTUSeq1UA7N7mogwQLAqawGBHQJ9JIapMl6uC7Y2nN9O4lYRtbQLBKpZ3xzIk9LrDyT3F/w+c3l/lVUz0X6lz746zNutl/6f6XKI5oeis7/b5rMHHYYE=";
PublicKey publicKey = stringToPublicKey(PCMSPublicKey);
byte[] enctyptedText = null;
try
{
final Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
enctyptedText = cipher.doFinal(base64Decode(data));
}
catch (Exception ex)
{
ex.printStackTrace();
}
return new String(enctyptedText);
}
public static byte[] base64Decode(String encodedString)
{
Base64 myBase64 = new Base64();
return myBase64.decode(encodedString);
}
public static PrivateKey stringToPrivateKey(String privateKeyString) throws GeneralSecurityException
{
byte[] clear = base64Decode(privateKeyString);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(clear);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey priv = fact.generatePrivate(keySpec);
Arrays.fill(clear, (byte) 0);
return priv;
}
public static PublicKey stringToPublicKey(String publicKeyString) throws GeneralSecurityException
{
byte[] clear = base64Decode(publicKeyString);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(clear);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pub = fact.generatePublic(keySpec);
Arrays.fill(clear, (byte) 0);
return pub;
}
}
I have the above java code that does encryption and decryption. The decryption works fine, which uses the private key, but when I ran the encryption part using the public key I hard-coded, I got the below errors,
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: DER input not a bit string
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at DJExampleDecryptCode.stringToPublicKey(DJExampleDecryptCode.java:109)
at DJExampleDecryptCode.encrypt(DJExampleDecryptCode.java:64)
at DJExampleDecryptCode.main(DJExampleDecryptCode.java:26)
Caused by: java.security.InvalidKeyException: IOException: DER input not a bit string
at sun.security.x509.X509Key.decode(X509Key.java:397)
at sun.security.x509.X509Key.decode(X509Key.java:403)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:83)
can anyone give me some suggestions? thanks a lot

Decrypting Rijndael in Android

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();
}

How do I use 3DES encryption/decryption in Java?

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;
}
}

Categories

Resources