encrypt message with symmetric key byte[] in Java - java

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

Related

DES in CBC mode must be caught or thrown error

I am trying to figure out why my DES code for cbc mode is not working. I get an error that says :
error: unreported exception NoSuchProviderException; must be caught or declared to be thrown
desCipher = Cipher.getInstance("DES/CBC/PKCS5Padding", "CB");
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;
public class JEncrytion
{
public static void main(String[] argv) {
try{
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey myDesKey = keygenerator.generateKey();
Cipher desCipher;
// Create the cipher
desCipher = Cipher.getInstance("DES/CBC/PKCS5Padding", "CB");
// Initialize the cipher for encryption
desCipher.init(Cipher.ENCRYPT_MODE, myDesKey);
//sensitive information
byte[] text = "hello world how are you".getBytes();
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);
// Initialize the same cipher for decryption
desCipher.init(Cipher.DECRYPT_MODE, myDesKey);
// Decrypt the text
byte[] textDecrypted = desCipher.doFinal(textEncrypted);
System.out.println("Text Decryted : " + new
String(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();
}
}
}
Do what the message says - declare an exception:
public static void main(String[] argv) throws Exception {
In your case a general exception is sufficient.
You need not to use Provider CB in Cipher.getInstance(). So, you will not get NoSuchProviderException anymore.
Just see below code, It works perfectly.
import java.security.InvalidKeyException;
import java.security.InvalidAlgorithmParameterException;
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.spec.IvParameterSpec;
import javax.crypto.SecretKey;
public class JEncryption
{
public static void main(String[] argv) {
try{
KeyGenerator keygenerator = KeyGenerator.getInstance("DES");
SecretKey myDesKey = keygenerator.generateKey();
Cipher desCipher;
// Create the cipher
desCipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
final IvParameterSpec iv = new IvParameterSpec(new byte[8]);
// Initialize the cipher for encryption
desCipher.init(Cipher.ENCRYPT_MODE, myDesKey,iv);
//sensitive information
byte[] text = "hello world how are you".getBytes();
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);
// Initialize the same cipher for decryption
desCipher.init(Cipher.DECRYPT_MODE, myDesKey,iv);
// Decrypt the text
byte[] textDecrypted = desCipher.doFinal(textEncrypted);
System.out.println("Text Decryted : " + new String(textDecrypted));
}catch(NoSuchAlgorithmException e){
e.printStackTrace();
}catch(NoSuchPaddingException e){
e.printStackTrace();
}catch(InvalidKeyException e){
e.printStackTrace();
}catch(InvalidAlgorithmParameterException e){
e.printStackTrace();
}catch(IllegalBlockSizeException e){
e.printStackTrace();
}catch(BadPaddingException e){
e.printStackTrace();
}
}
}

Blowfish encryption and decryption not working

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

Java AES: Generate Key using a single id as source

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

Hi I'm trying to do AES Encryption using JAVA Code Help me in converting?

I'm trying to convert JAVA Code into Objective - C language. I have a requirement where I should Use the same code that Android developers are using. Code follows as
import java.io.UnsupportedEncodingException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
public class EncDec {
public static void main(String args[])
{
String reqMessage="{\"accountType\":\"ALL\",\"uId\":\"c8ff46be-a083-4009-8a33-fc2d22cc40e3|123456784\",\"deviceId\":\"qvxy1234\"}";
Map requestMap=new HashMap();
requestMap.put("body", reqMessage);
String bodyString=(String) requestMap.get("body");
String authKey="M/98hZivBqJQftMHsPvMgg&&";
String encString= encode(authKey,bodyString);
System.out.println("encString ::: "+ encString);
String decString= decode(authKey,encString);
System.out.println("decString ::: "+ decString);
}
public static String encode(String keyString, String stringToEncode) throws NullPointerException {
if (keyString.length() == 0 || keyString == null) {
throw new NullPointerException("Please give Password");
}
if (stringToEncode.length() == 0 || stringToEncode == null) {
throw new NullPointerException("Please give text");
}
try {
SecretKeySpec skeySpec = getKey(keyString);
byte[] clearText = stringToEncode.getBytes("UTF8");
// IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
byte[] encryptedByte=cipher.doFinal(clearText);
String encrypedValue = new String(Base64.encodeBase64(encryptedByte));
System.out.println("Encrypted: " + stringToEncode + " -> " + encrypedValue);
return encrypedValue;
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return "";
}
/**
* Decodes a String using AES-128 and Base64
*
* #param context
* #param password
* #param text
* #return desoded String
*/
public static String decode(String password, String text) throws NullPointerException {
if (password.length() == 0 || password == null) {
throw new NullPointerException("Please give Password");
}
if (text.length() == 0 || text == null) {
throw new NullPointerException("Please give text");
}
try {
SecretKey key = getKey(password);
// IMPORTANT TO GET SAME RESULTS ON iOS and ANDROID
final byte[] iv = new byte[16];
Arrays.fill(iv, (byte) 0x00);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
byte[] encrypedPwdBytes = Base64.decodeBase64(text.getBytes());
// cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.DECRYPT_MODE, key, ivParameterSpec);
byte[] decrypedValueBytes = (cipher.doFinal(encrypedPwdBytes));
String decrypedValue = new String(decrypedValueBytes);
System.out.println("Decrypted: " + text + " -> " + decrypedValue);
return decrypedValue;
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (BadPaddingException e) {
e.printStackTrace();
} catch (NoSuchPaddingException e) {
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
e.printStackTrace();
}
return "";
}
/**
* Generates a SecretKeySpec for given password
*
* #param password
* #return SecretKeySpec
* #throws UnsupportedEncodingException
*/
private static SecretKeySpec getKey(String password) throws UnsupportedEncodingException {
// You can change it to 256 if you wish
int keyLength = 128;
byte[] keyBytes = new byte[keyLength / 8];
// explicitly fill with zeros
Arrays.fill(keyBytes, (byte) 0x0);
// if password is shorter then key length, it will be zero-padded
// to key length
byte[] passwordBytes = password.getBytes("UTF-8");
int length = passwordBytes.length < keyBytes.length ? passwordBytes.length : keyBytes.length;
System.arraycopy(passwordBytes, 0, keyBytes, 0, length);
SecretKeySpec key = new SecretKeySpec(keyBytes, "AES");
return key;
}
}
So I want this to be converted in to Objective C. I don't know how to do this. Help me out in this !!
I have searched some code in JAVA And I tried of doing it. But the problem is it will give some other decrypted data but not the exact one that gives using this code. So If I convert the same thing I may get the exact code I guess.
People might be knowing JAVA as well as Objective c here. Those people can help me i guess.
I'm not sure, but you can try it :).
For the encode phase :
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
// Cipher is not thread safe
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, ivParameterSpec);
byte[] encryptedByte=cipher.doFinal(clearText);
String encrypedValue = new String(Base64.encodeBase64(encryptedByte));
Using CCCrypt in Obj-C :
CCCryptorStatus CCCrypt(
CCOperation op, //is kCCEncrypt in your case
CCAlgorithm alg, //is kCCAlgorithmAES128
CCOptions options, //is kCCModeCBC
const void *key, //may be skeySpec
size_t keyLength,
const void *iv, // is your iv key : ivParameterSpec
const void *dataIn,
size_t dataInLength,
void *dataOut, /* data RETURNED here */
size_t dataOutAvailable,
size_t *dataOutMoved)
__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0);
Please reference : CCCrypt decrypting in AES CBC works even without IV
for more information, Hope this help you.
Hey I got the answer go through these links below you will get the exact code for Android and IOS...
https://gist.github.com/m1entus/f70d4d1465b90d9ee024

error on Decryption: javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher

Here it is program for encryption and Decryption using DES. program is working when passing the output of encryption directly for decryption. but when taking input from user in string to decrypt, it showing this exception. how to pass cipher string in bytes so it becomes compatible for decryption?
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKeyFactory;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.DESKeySpec;
import javax.xml.bind.DatatypeConverter;
public class DESEncryptionDecryption {
private static Cipher encryptCipher;
private static Cipher decryptCipher;
public static void main(String[] args) throws InvalidKeySpecException {
try {
String desKey = "0123456789abcdef"; // value from user
byte[] keyBytes = DatatypeConverter.parseHexBinary(desKey);
System.out.println(keyBytes);
SecretKeyFactory factory = SecretKeyFactory.getInstance("DES");
SecretKey key = factory.generateSecret(new DESKeySpec(keyBytes));
encryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
encryptCipher.init(Cipher.ENCRYPT_MODE, key);
byte[] encryptedData = encryptData("Confidential data"); //String from user
String s=encryptedData.toString();//String input to decrypt From user
byte[] bb=s.getBytes();
decryptCipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
decryptCipher.init(Cipher.DECRYPT_MODE, key);
decryptData(bb); //Exception
}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();
}}
//method for encryption
private static byte[] encryptData(String data)
throws IllegalBlockSizeException, BadPaddingException {
System.out.println("Data Before Encryption :" + data);
byte[] dataToEncrypt = data.getBytes();
byte[] encryptedData = encryptCipher.doFinal(dataToEncrypt);
System.out.println("Encryted Data: " + encryptedData);
return encryptedData;
}
//method for decryption
private static void decryptData(byte[] data)
throws IllegalBlockSizeException, BadPaddingException {
byte[] textDecrypted = decryptCipher.doFinal(data); //Exception trigered here
System.out.println("Decryted Data: " + new String(textDecrypted));
}}
I can't easily tell whether this is all that's wrong, but this is definitely wrong:
byte[] encryptedData = encryptData("Confidential data"); //String from user
String s=encryptedData.toString();//String input to decrypt From user
byte[] bb=s.getBytes();
Just decrypt encryptedData instead of of bb. Your s value is basically useless, because you've called toString() on a byte[], which won't give you what you're apparently expecting. The value of s will be something like "[B#15db9742" because arrays don't override toString() in Java.
If you really want to turn arbitrary binary data (such as the result of encryption) into text, use base64 instead. Encode the result of encryption using base64 to get a string, and then later base64-decode it from the string to a byte array, then decrypt that byte array.
Oh, and I'd strongly recommend against using String(byte[]) or String.getBytes() too - always use the overloads which take a character encoding instead.

Categories