I need to generate a Key in order to use it for encryption and decryption using an AES cipher.
The key must be generated on runtime using a single id value.
How could I generate a Key taking a single string as source?
Hope this can help you.
package com.lahiru.security;
import java.io.UnsupportedEncodingException;
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;
public static void main(String[] args){
String id = "00001";
String plainText = "This is plain text";
String cipherText = encrypt(plainText, id);
System.out.println("Cipher Text after encrption ::: " + cipherText);
System.out.println("Plain Text after decryption ::: " + decrypt(cipherText, id));
}
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);
secretKey = new SecretKeySpec(key, "AES");
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static String encrypt(String strToEncrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
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 static String decrypt(String strToDecrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
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;
}
}
Related
I want to check my result of encryption and decryption with this website
https://8gwifi.org/CipherFunctions.jsp How do I input in the secret key on the website?
This is my java code.
public static void main(String[] args) throws Exception {
final String secretKey = "PASSWORD";
String originalString = "Java Web Developer";
String encryptedString = AESUtils.encrypt(originalString, secretKey) ;
String decryptedString = AESUtils.decrypt(encryptedString, secretKey) ;
System.out.println("Original : " + originalString); //Original : Java Web Developer
System.out.println("Encryption : " + encryptedString); //Encryption : 43Ak2VHK368eandGGYWX2WvbcimGGAEsPdCSjEatjR0=
System.out.println("Decryption : " + decryptedString); //Decryption : Java Web Developer
}
public class AESUtils {
private static SecretKeySpec secretKey;
private static byte[] key;
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);
secretKey = new SecretKeySpec(key, "AES");
byte encoded[] = secretKey.getEncoded();
/*
* Encodes the specified byte array into a String using Base64 encoding
* scheme
*/
String encodedKey = Base64.getEncoder().encodeToString(encoded);
System.out.println("SecretKey: " + encodedKey); //SecretKey: ESu3kTBHkd3PaS4p/VzxSQ==
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static String encrypt(String strToEncrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
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 static String decrypt(String strToDecrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
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;
}
}
I tried inputting the secret key with "ESu3kTBHkd3PaS4p/VzxSQ==", But the result of encryption does not match the result of encryption from the java program.
My Java program retured encryption to be 43Ak2VHK368eandGGYWX2WvbcimGGAEsPdCSjEatjR0=
I have an AES class in java, my intention to decrypt a JSON string in js which encrypted in java,
here is my encryption code
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);
System.out.println(Arrays.toString(key));
secretKey = new SecretKeySpec(key, "AES");
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public static String encrypt(String strToEncrypt, String secret)
{
try
{
setKey(secret);
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
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;
}
And I have tried many way using Cryptojs
var secret = "llssshhhhhhhhhhh";
var new_secret = CryptoJS.SHA1(getBytes(secret));
console.log(getBytes(new_secret.toString()));
var test = "<Encrypted Text>";
var bytes = CryptoJS.AES.decrypt(test, new_secret, {
mode: CryptoJS.mode.ECB,
padding: CryptoJS.pad.Pkcs7
});
var originalText = bytes.toString(CryptoJS.enc.Utf8);
console.log({originalText});
But I am not getting the original text even its return a blank string.
Can anyone know I am wrong?
Requirements:
Encrypt string using AES Encryption(with GCMParameterSpec and nonce).
Append nonce to Encrypted String to use it later for decryption.
Decrypt string by extracting nonce and the string to decrypt.
I have written the code to encrypt and decrypt the string as required but i am facing "Error while decrypting Tag mismatch!"
Could someone please help me identify the problem. Thanks!
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES {
private static SecretKeySpec secretKey;
private static byte[] key;
private static final String ENCODING_TYPE = "UTF-8";
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION_VALUE = "AES/GCM/NoPadding";
public static void setKey(String myKey, String hashingType) {
MessageDigest sha = null;
try {
key = myKey.getBytes(ENCODING_TYPE);
sha = MessageDigest.getInstance(hashingType);
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, ALGORITHM);
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException "+e.getMessage());
} catch (UnsupportedEncodingException e) {
System.out.println("UnsupportedEncodingException "+e.getMessage());
} catch (Exception e) {
System.out.println("Exception Occured! "+e.getMessage());
}
}
public static String encrypt(String strToEncrypt, String secret, String hashingType) {
String encryptedString = null;
try {
byte[] nonce = new byte[12];
setKey(secret,hashingType);
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(nonce);
final Cipher encryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
byte[] cipheredString = encryptCipher.doFinal(strToEncrypt.getBytes());
ByteBuffer byteBuffer = ByteBuffer.allocate(nonce.length + cipheredString.length);
byteBuffer.put(nonce);
byteBuffer.put(cipheredString);
encryptedString = Base64.getEncoder().encodeToString(byteBuffer.array()); //Encoding the ByteArrayOutputStream result object to Base64 format
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException "+e.getMessage());
} catch (Exception e) {
System.out.println("Error while encrypting "+e.getMessage());
}
return encryptedString;
}
public static String decrypt(String strToDecrypt, String secret, String hashingType) {
String decryptedString = null;
try {
byte[] nonce = new byte[12];
setKey(secret,hashingType);
final Cipher decryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(strToDecrypt));
byteBuffer.get(nonce);
byte[] cipheredString = new byte[byteBuffer.remaining()];
byteBuffer.get(cipheredString);
decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
decryptedString = new String(decryptCipher.doFinal(cipheredString));
} catch (Exception e) {
System.out.println("Error while decrypting "+e.getMessage());
}
return decryptedString;
}
}
public class TestAESEncrypt {
public static void main(String[] args) {
final String secretKey = "NEWTEST#Key123";
String originalString = "Gamer_123.aa01#gmail.com";
String encryptedString = AESEncryption.encrypt(originalString, secretKey, "SHA-256");
System.out.println("String to Encrypt : "+originalString);
System.out.println("Encrypted String : "+encryptedString);
}
}
public class TestAESDecryption {
public static void main(String[] args) {
final String secretKey = "NEWTEST#Key123";
String encryptedData = "ey4E+5zNPx4WLx5q0Srf7d1TN/sAzsdYuVmnihXQoA/yoYoxAO/ygrtuh+Zr9rZQ"; //Paste the encrypted string here
String decryptedString = AESEncryption.decrypt(encryptedData, secretKey, "SHA-256") ;
System.out.println("Encrypted String : "+encryptedData);
System.out.println("Decrypted String: "+decryptedString);
}
}
This will never work:
encryptedString = new String(cipher.doFinal(strToEncrypt.getBytes())); //Creating a ciphered string
encryptedString += new String(nonce); //Appending nonce to the encrypted string
encryptedString = new String(Base64.getEncoder().encode(encryptedString.getBytes())); //Encoding ciphered string to Base64 format
Once you attempt to convert the raw bytes to a string you have likely corrupted the data. Base64 encoding it afterward will not save you. Instead, you must do something like:
ByteArrayOutputStream result = new ByteArrayOutputStream();
result.write(nonce);
result.write(cipher.doFinal(strToEncrypt.getBytes()));
String encryptedString = Base64.getEncoder().encodeToString(result.toByteArray());
Also, I noticed your nonce is only 8 bytes. That's probably too short, you should make it 12 bytes.
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Arrays;
import java.util.Base64;
import javax.crypto.Cipher;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class AES {
private static SecretKeySpec secretKey;
private static byte[] key;
private static final String ENCODING_TYPE = "UTF-8";
private static final String ALGORITHM = "AES";
private static final String TRANSFORMATION_VALUE = "AES/GCM/NoPadding";
public static void setKey(String myKey, String hashingType) {
MessageDigest sha = null;
try {
key = myKey.getBytes(ENCODING_TYPE);
sha = MessageDigest.getInstance(hashingType);
key = sha.digest(key);
key = Arrays.copyOf(key, 16);
secretKey = new SecretKeySpec(key, ALGORITHM);
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException "+e.getMessage());
} catch (UnsupportedEncodingException e) {
System.out.println("UnsupportedEncodingException "+e.getMessage());
} catch (Exception e) {
System.out.println("Exception Occured! "+e.getMessage());
}
}
public static String encrypt(String strToEncrypt, String secret, String hashingType) {
String encryptedString = null;
try {
byte[] nonce = new byte[12];
setKey(secret,hashingType);
SecureRandom random = SecureRandom.getInstanceStrong();
random.nextBytes(nonce);
final Cipher encryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
encryptCipher.init(Cipher.ENCRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
byte[] cipheredString = encryptCipher.doFinal(strToEncrypt.getBytes());
ByteBuffer byteBuffer = ByteBuffer.allocate(nonce.length + cipheredString.length);
byteBuffer.put(nonce);
byteBuffer.put(cipheredString);
encryptedString = Base64.getEncoder().encodeToString(byteBuffer.array()); //Encoding the ByteArrayOutputStream result object to Base64 format
} catch (NoSuchAlgorithmException e) {
System.out.println("NoSuchAlgorithmException "+e.getMessage());
} catch (Exception e) {
System.out.println("Error while encrypting "+e.getMessage());
}
return encryptedString;
}
public static String decrypt(String strToDecrypt, String secret, String hashingType) {
String decryptedString = null;
try {
byte[] nonce = new byte[12];
setKey(secret,hashingType);
final Cipher decryptCipher = Cipher.getInstance(TRANSFORMATION_VALUE);
ByteBuffer byteBuffer = ByteBuffer.wrap(Base64.getDecoder().decode(strToDecrypt));
byteBuffer.get(nonce);
byte[] cipheredString = new byte[byteBuffer.remaining()];
byteBuffer.get(cipheredString);
decryptCipher.init(Cipher.DECRYPT_MODE, secretKey, new GCMParameterSpec(16 * 8, nonce));
decryptedString = new String(decryptCipher.doFinal(cipheredString));
} catch (Exception e) {
System.out.println("Error while decrypting "+e.getMessage());
}
return decryptedString;
}
}
So I'm using a simple Blowfish encryption/decryption for an application I'm making. It works sometimes but isn't reliable.
Form template being encrypted:
email#gmail.com
message
END
It works perfectly when I use an email like test1#gmail.com or test2#gmail.com.
When I use my personal email: tywemc#gmail.com, the form is encrypted but when it's decrypted, it returns î/ÅÝ®Îmail.comÄþ4œ’>L/ND
So it seems like it decrypts part of the form but not the whole thing and I can't figure out why. It seems to decrypts other forms partially with different real emails but still not completely. I'm using a static key within the Crypto.java class for simplicity.
I've tried to make sure the longer emails were causing it to not work because of a block size or string length issue but I don't think that's the problem.
Crypto.java
package core;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Crypto {
private static String key = "key12345";
public static String encrypt(String strClearText,String strKey) {
String strData = "";
try {
SecretKeySpec skeyspec = new SecretKeySpec(key.getBytes(), "Blowfish");
System.out.println("Ëncryption keyspec: " + skeyspec.toString());
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, skeyspec);
byte[] encrypted = cipher.doFinal(strClearText.getBytes());
strData = new String(encrypted);
} catch (Exception e) {
e.printStackTrace();
}
return strData;
}
public static String decrypt(String strEncrypted,String strKey) {
String strData = "";
try {
SecretKeySpec skeyspec = new SecretKeySpec(key.getBytes(),"Blowfish");
System.out.println("Decryption keyspec: " + skeyspec.toString());
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.DECRYPT_MODE, skeyspec);
byte[] decrypted = cipher.doFinal(strEncrypted.getBytes());
strData = new String(decrypted);
} catch (Exception e) {
e.printStackTrace();
}
return strData;
}
}
Should I use a different encryption type/method or is there something I'm doing wrong? Thanks in advance!
Updated Code:
package core;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Crypto {
private static String key = "key12345";
public static byte[] encrypt(String strClearText, String strKey) {
byte[] encrypted = null;
try {
SecretKeySpec skeyspec = new SecretKeySpec(key.getBytes(), "Blowfish");
System.out.println("Ëncryption keyspec: " + skeyspec.toString());
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.ENCRYPT_MODE, skeyspec);
encrypted = cipher.doFinal(strClearText.getBytes());
// strData = new String(encrypted);
} catch (Exception e) {
e.printStackTrace();
}
return encrypted;
}
public static String decrypt(byte[] strEncrypted, String strKey) {
String strData = "";
try {
SecretKeySpec skeyspec = new SecretKeySpec(key.getBytes(),"Blowfish");
System.out.println("Decryption keyspec: " + skeyspec.toString());
Cipher cipher = Cipher.getInstance("Blowfish");
cipher.init(Cipher.DECRYPT_MODE, skeyspec);
byte[] decrypted = cipher.doFinal(strEncrypted);
strData = new String(decrypted);
} catch (Exception e) {
e.printStackTrace();
}
return strData;
}
}
[B#164b077d is what is passed in as strEncrypted.
Error
javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher
I want to take a piece of plain text, a symmetric key(from a previous computation) in the form of a byte[] and output a cipher text. cipherText = encrypt(plainText,sharedSecret)
How do I merge the plain text and the shared secret?
public static String encrypt(String plainText, byte[] sharedSecret){
String cipherText = "";
//combining the sharedSecret with the plainText
return cipherText;
}
Check this code for symmetric key encryption. You can refactor to suit your encrypt method.
import java.security.AlgorithmParameters;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
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.IvParameterSpec;
public class SymmEncryption {
public static void main(String[] args) throws InvalidAlgorithmParameterException {
try {
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
keyGenerator.init(256); // 56 is the keysize. Fixed for DES
//Initialization Vector
byte[] iv = "1234567812345678".getBytes();
IvParameterSpec ivSpec = new IvParameterSpec(iv);
SecretKey secretKey = keyGenerator.generateKey();
System.out.println(secretKey.getFormat());
Cipher desCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//algorithm/mode/padding
//Electronic Codebook (ECB)
System.out.format("Secret Key: %s--%s--%s%n", secretKey.getAlgorithm(), secretKey.getFormat(), secretKey.getEncoded());
// Initialize the cipher for encryption
desCipher.init(Cipher.ENCRYPT_MODE, secretKey, ivSpec);
// sensitive information
byte[] text = "No body can see me".getBytes();
System.out.println("Hex text: " + byteArrayToHex(text));
System.out.println("Text [Byte Format] : " + text);
System.out.println("Text : " + new String(text));
// Encrypt the text
byte[] textEncrypted = desCipher.doFinal(text);
System.out.println("Text Encryted : " + textEncrypted);
System.out.println("Hex Encrypted text: " + byteArrayToHex(textEncrypted));
// Initialize the same cipher for decryption
desCipher.init(Cipher.DECRYPT_MODE, secretKey, ivSpec);
// Decrypt the text
byte[] textDecrypted = desCipher.doFinal(textEncrypted);
System.out.println("Text Decryted : " + new String(textDecrypted));
System.out.println("Hex Decrypted text: " + byteArrayToHex(textDecrypted));
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
}
}
static String byteArrayToHex(byte[] a) {
StringBuilder sb = new StringBuilder();
for (byte b : a)
sb.append(String.format("%02x", b & 0xff));
return sb.toString();
}
}