Hy ,

I have to encrypt a message and then decrypt it.
I have this code , but i need to save the encrypted string in a database and the code generates a random key every time.
I could save the string and the key in the database but that is not ok .
How can i make my own key without needing to generate it every time?

import java.security.InvalidKeyException;
import java.security.Key;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

   public class LocalEncrypter {

        private static String algorithm = "DESede";
        private static Key key = null;
        //private static int[] key = new int[24];
        private static Cipher cipher = null;

        private static void setUp() throws Exception {
            key = KeyGenerator.getInstance(algorithm).generateKey();
            //SecretKey key = key.getAlgorithm().
            cipher = Cipher.getInstance(algorithm);
        }

        public static void main(String[] args) 
           throws Exception {
            setUp();
            
            byte[] encryptionBytes = null;
            String input = "1234";
            System.out.println("Entered: " + input);
            encryptionBytes = encrypt(input);
            System.out.println(
              "Recovered: " + decrypt(encryptionBytes));
        }

        private static byte[] encrypt(String input)
            throws InvalidKeyException, 
                   BadPaddingException,
                   IllegalBlockSizeException {
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] inputBytes = input.getBytes();
            return cipher.doFinal(inputBytes);
        }

        private static String decrypt(byte[] encryptionBytes)
            throws InvalidKeyException, 
                   BadPaddingException,
                   IllegalBlockSizeException {
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] recoveredBytes = 
              cipher.doFinal(encryptionBytes);
            String recovered = 
              new String(recoveredBytes);
            return recovered;
          }
   }

I don`t want to use sun.misc.base64 ....

Recommended Answers

All 10 Replies

Did I post some code for this problem earlier somewhere?
You need to use a String to generate the key. Look at what the classes in this code does:

// Create the key
        KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), iv, iterationCount);
        SecretKey key = SecretKeyFactory.getInstance(ALG).generateSecret(keySpec);
import java.security.InvalidKeyException;
import java.security.*;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;

   public class LocalEncrypter {

        private static String algorithm = "PBEWithMD5AndDES";
       //private static Key key = null;
        private static Cipher cipher = null;
		private static SecretKey key;

        private static void setUp() throws Exception {
            ///key = KeyGenerator.getInstance(algorithm).generateKey();
        	SecretKeyFactory factory = SecretKeyFactory.getInstance(algorithm);
        	String pass1 = "thisIsTheSecretKeyProvidedByMe";
        	byte[] pass = pass1.getBytes(); 
        	SecretKey key = factory.generateSecret(new DESedeKeySpec(pass));
            cipher = Cipher.getInstance(algorithm);
        }

        public static void main(String[] args) 
           throws Exception {
            setUp();
            
            byte[] encryptionBytes = null;
            String input = "1234";
            System.out.println("Entered: " + input);
            encryptionBytes = encrypt(input);
            System.out.println(
              "Recovered: " + decrypt(encryptionBytes));
        }

        private static byte[] encrypt(String input)
            throws InvalidKeyException, 
                   BadPaddingException,
                   IllegalBlockSizeException {
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] inputBytes = input.getBytes();
            return cipher.doFinal(inputBytes);
        }

        private static String decrypt(byte[] encryptionBytes)
            throws InvalidKeyException, 
                   BadPaddingException,
                   IllegalBlockSizeException {
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] recoveredBytes = 
              cipher.doFinal(encryptionBytes);
            String recovered = 
              new String(recoveredBytes);
            return recovered;
          }
   }

Now it gives me the error : Invalid Key Spec

what source line does the error occur on?

Exception in thread "main" java.security.spec.InvalidKeySpecException: Invalid key spec
	at com.sun.crypto.provider.PBEKeyFactory.engineGenerateSecret(PBEKeyFactory.java:114)
	at javax.crypto.SecretKeyFactory.generateSecret(SecretKeyFactory.java:335)
	at LocalEncrypter.setUp(LocalEncrypter.java:22)
	at LocalEncrypter.main(LocalEncrypter.java:28)

This is the error

Your code that creates the SecretKey is different than I posted. I don't know what you are doing.
Did you try using the classes that I used as I used them?

Thank You very much , it worked how you said.
I rewrote the hole code and now it works.

1 more question

After encryption i save in the database a string like this :
77, -65, 75, -114, -100, 40, -51, 38, 38, 56, 72, 25, 74, 120, -72, -85

And when i decode the string i need it to be BYTE[].
How can i insert the values from the string in the byte[] field.

Are you asking how to convert a byte to a Byte? (Not BYTE)
Look at the Byte class's constructor to see how to create a Byte from a byte.
Then use a loop.

Or post an example of what you have as input and what you want as output.

I have the string :

77, -65, 75, -114, -100, 40, -51, 38, 38, 56, 72, 25, 74, 120, -72, -85

And if i want to decode it , i need it like byte [].


If i use it as :

byte[] bytes = new byte[]{77, -65, 75, -114, -100, 40, -51, 38, 38, 56, 72, 25, 74, 120, -72, -85}

It works . But i need a method to do it every time i am get a string like that from database.


I also have this code for that but i get an error : The method valueOf(String) is undefined for the type byte. At line 7

String response = "[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]";      // response from the database

		String[] byteValues = response.substring(1, response.length() - 1).split(",");
		byte[] bytes = new byte[byteValues.length];

		for (int i=0, len=bytes.length; i<len; i++) {
		   bytes[i] = Byte.valueof(byteValues[i].trim());
		   
		}

		String str = new String(bytes);
		
	}

Try this:

String response = "[-47, 1, 16, 84, 2, 101, 110, 83, 111, 109, 101, 32, 78, 70, 67, 32, 68, 97, 116, 97]";      // response from the database

		String[] byteValues = response.substring(1, response.length() - 1).split(",");
		byte[] bytes = new byte[byteValues.length];

		for (int i=0, len=bytes.length; i<len; i++) {
		   bytes[i] = (byte)Integer.parseInt(byteValues[i].trim());
		}
                System.out.println(response);
		System.out.println(Arrays.toString(bytes));

Thank you very much for your help and time , everything worked very well

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.