Welcome to the Java Programming Forums


The professional, friendly Java community. 21,500 members and growing!


The Java Programming Forums are a community of Java programmers from all around the World. Our members have a wide range of skills and they all have one thing in common: A passion to learn and code Java. We invite beginner Java programmers right through to Java professionals to post here and share your knowledge. Become a part of the community, help others, expand your knowledge of Java and enjoy talking with like minded people. Registration is quick and best of all free. We look forward to meeting you.


>> REGISTER NOW TO START POSTING


Members have full access to the forums. Advertisements are removed for registered users.

Results 1 to 7 of 7

Thread: Converting a SecretKey to String and back again

  1. #1
    Member
    Join Date
    Oct 2013
    Posts
    77
    Thanks
    55
    Thanked 0 Times in 0 Posts

    Default Converting a SecretKey to String and back again

    Greetings!

    I'm using the class below to encrypt and decrypt data in my program. It works rather well with the exception that I can't for the mind of me get the recreation of the key to work. When the program runs the first time, it creates a key and saves it to Data.txt. This part works fine, and there are no errors, the encryption and decryption works until I reload the program and it tries to recreate the key using the String in the .txt.

    read = loadFile.readline();
    byte[] data = read.getBytes("UTF-8");
    key = new SecretKeySpec(data, 0, data.length, "PBEWithMD5AndDES");

    I've looked at:
    java - convert Byte Array to Secret Key - Stack Overflow
    java - Converted secret key into bytes, how to convert it back to secrect key? - Stack Overflow

    and a number of other sites which didn't help, both of these however suggested the key = new SecretKeySpec.

    The actual key became: "[B@79fe3f51"
    Whereas the recreated key became: "[B@3e1d1648"

    So they are close, but not the same.

    I create the original key like this:

    key = SecretKeyFactory.getInstance("PBEWithMD5AndDES").generateSecret(keySpec);

    Encryption.java:
    public class Encryption {
     
          public Cipher dcipher, ecipher;
     
          // Responsible for setting, initializing this object's encrypter and
          // decrypter Chipher instances
          Encryption(String passPhrase) {
     
                 // 8-bytes Salt
                 byte[] salt = { (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
                              (byte) 0x56, (byte) 0x34, (byte) 0xE3, (byte) 0x03 };
     
                 // Iteration count
                 int iterationCount = 19;
                 boolean loaded = false;
     
                 try {
                        // Generate a temporary key. In practice, you would save this key
                        // Encrypting with DES Using a Pass Phrase
                        KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(), salt,
                                     iterationCount);
     
                        SecretKey key;
     
     
                    	URL jarUrl = MainFrame.class.getProtectionDomain().getCodeSource().getLocation();
                    	File jarFile = null;
                		try {
                			jarFile = new File(jarUrl.toURI());
                		} catch (URISyntaxException e) {
                			e.printStackTrace();
                		}
                    	File jarDir = jarFile.getParentFile();   // Directory of the jar
     
     
                    	String filePath = "/data/Data.txt";
                        File f = new File(jarDir + filePath);
     
                        String read = "";
                        if(f.exists())
                        {
                        	        BufferedReader loadFile;
    						try {
    							loadFile = new BufferedReader(new FileReader(f));
    							try {
    								read = loadFile.readLine();
    								 loadFile.close();
    								loaded = true;
     
    								byte[] data = read.getBytes("UTF-8");
     
    								key = new SecretKeySpec(data, 0, data.length, "PBEWithMD5AndDES");
     
    								  JOptionPane.showMessageDialog(null, "Key in string: " + read);
     
    							} catch (IOException e) {
    								e.printStackTrace();
    							}
     
     
    						} catch (FileNotFoundException e) {
    							e.printStackTrace();
    						}
     
     
                        }else
                        {
                        	key = SecretKeyFactory.getInstance("PBEWithMD5AndDES")
                                    .generateSecret(keySpec);
     
                        }
     
                        ecipher = Cipher.getInstance(key.getAlgorithm());
                        dcipher = Cipher.getInstance(key.getAlgorithm());
     
                        // Prepare the parameters to the cipthers
                        AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt,
                                     iterationCount);
     
                        ecipher.init(Cipher.ENCRYPT_MODE, key, paramSpec);
                        dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
     
     
                        //			Saving the key!
                        //**************************************************************
                        if(loaded == false)
                        {
                            try
                            {
     
                            	jarFile = null;
                    			try {jarFile = new File(jarUrl.toURI());} 
                    			catch (URISyntaxException e) {e.printStackTrace();}
     
                                String fileName = "/data/Data.txt";
     
                                File txtFile = new File(jarDir + fileName);
     
                                if(!txtFile.exists())
                                {
                                	txtFile.createNewFile();
                                	txtFile.mkdirs();
                                }
     
                                FileWriter saveFile = new FileWriter(jarDir + fileName);
     
     
                                byte[] theKey = key.getEncoded();
     
                                String fileData = theKey.toString();
     
     
                                saveFile.write(fileData);
                                saveFile.close();
                            } catch (IOException e) {
     
                                e.printStackTrace();
                            }
                        }
     
     
     
                        //****************************************************************
     
                 } catch (InvalidAlgorithmParameterException e) {
                        System.out.println("EXCEPTION: InvalidAlgorithmParameterException");
                 } catch (InvalidKeySpecException e) {
                        System.out.println("EXCEPTION: InvalidKeySpecException");
                 } catch (NoSuchPaddingException e) {
                        System.out.println("EXCEPTION: NoSuchPaddingException");
                 } catch (NoSuchAlgorithmException e) {
                        System.out.println("EXCEPTION: NoSuchAlgorithmException");
                 } catch (InvalidKeyException e) {
                        System.out.println("EXCEPTION: InvalidKeyException");
                 }
          }
     
          // Encrpt Password
     
          @SuppressWarnings("restriction")
    	protected String encrypt(String str) {
                 try {
                        // Encode the string into bytes using utf-8
                        byte[] utf8 = str.getBytes("UTF8");
                        // Encrypt
                        byte[] enc = ecipher.doFinal(utf8);
                        // Encode bytes to base64 to get a string
                        return new sun.misc.BASE64Encoder().encode(enc);
     
                 } catch (BadPaddingException e) {
                 } catch (IllegalBlockSizeException e) {
                 } catch (UnsupportedEncodingException e) {
                 }
                 return null;
          }
     
          // Decrpt password
          // To decrypt the encryted password
          protected String decrypt(String str) {
                 Cipher dcipher = null;
                 try {
                        byte[] salt = { (byte) 0xA9, (byte) 0x9B, (byte) 0xC8, (byte) 0x32,
                                     (byte) 0x56, (byte) 0x34, (byte) 0xE3, (byte) 0x03 };
                        int iterationCount = 19;
                        try {
                              String passPhrase = "";
                              KeySpec keySpec = new PBEKeySpec(passPhrase.toCharArray(),
                                            salt, iterationCount);
                              SecretKey key = SecretKeyFactory
                                            .getInstance("PBEWithMD5AndDES")
                                            .generateSecret(keySpec);
                              dcipher = Cipher.getInstance(key.getAlgorithm());
                              // Prepare the parameters to the cipthers
                              AlgorithmParameterSpec paramSpec = new PBEParameterSpec(salt,
                                            iterationCount);
                              dcipher.init(Cipher.DECRYPT_MODE, key, paramSpec);
                        } catch (InvalidAlgorithmParameterException e) {
                              System.out
                                            .println("EXCEPTION: InvalidAlgorithmParameterException");
                        } catch (InvalidKeySpecException e) {
                              System.out.println("EXCEPTION: InvalidKeySpecException");
                        } catch (NoSuchPaddingException e) {
                              System.out.println("EXCEPTION: NoSuchPaddingException");
                        } catch (NoSuchAlgorithmException e) {
                              System.out.println("EXCEPTION: NoSuchAlgorithmException");
                        } catch (InvalidKeyException e) {
                              System.out.println("EXCEPTION: InvalidKeyException");
                        }
                        // Decode base64 to get bytes
                        @SuppressWarnings("restriction")
    					byte[] dec = new sun.misc.BASE64Decoder().decodeBuffer(str);
                        // Decrypt
                        byte[] utf8 = dcipher.doFinal(dec);
                        // Decode using utf-8
                        return new String(utf8, "UTF8");
                 } catch (BadPaddingException e) {
                 } catch (IllegalBlockSizeException e) {
                 } catch (UnsupportedEncodingException e) {
                 } catch (IOException e) {
                 }
                 return null;
          }
    }

    Most of the relevant things should be outlined above, if there's anything else you want outlined, please don't hesitate to comment!


  2. #2
    Super Moderator Norm's Avatar
    Join Date
    May 2010
    Location
    SW Missouri
    Posts
    20,067
    Thanks
    47
    Thanked 2,146 Times in 2,119 Posts

    Default Re: Converting a SecretKey to String and back again

    The actual key became: "[B@79fe3f51"
    Whereas the recreated key became: "[B@3e1d1648"
    Those Strings are what is returned by the toString() method for a byte array. They do NOT show the contents of the byte arrays. To see what is in the arrays use the Arrays class's toString() method to format the array for printing:
    System.out.println("an ID "+ java.util.Arrays.toString(theArrayName));
    If you don't understand my answer, don't ignore it, ask a question.

  3. #3
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    4,469
    My Mood
    Mellow
    Thanks
    151
    Thanked 609 Times in 596 Posts

    Default Re: Converting a SecretKey to String and back again

    I believe the root of your problem is that you're treating something like plain text that is not plain text. You might find this StackOverflow discussion helpful, but from that you might do further research into writing/restoring encoded character arrays.

  4. #4
    Member
    Join Date
    Oct 2013
    Posts
    77
    Thanks
    55
    Thanked 0 Times in 0 Posts

    Default Re: Converting a SecretKey to String and back again

    I'm afraid I haven't been able to make any progress, it feels like it should be so easy to do yet everywhere I look someone has done it differently, and none of the solutions I find seems to work for me. =/

    The solution in the discussion you linked is what made me create the other thread asking how to properly import a library, because the solution he used made use of such a library. I was however in the end unsuccessful in getting it to work, thus that entire solution no longer works.

    Would it at all be possible to create a specific key that is always used? I know it's not at all safe, but in this case it's more important that the encryption works at all, than is done in a optimal way.

  5. #5
    Super Moderator
    Join Date
    Jun 2013
    Location
    So. Maryland, USA
    Posts
    4,469
    My Mood
    Mellow
    Thanks
    151
    Thanked 609 Times in 596 Posts

    Default Re: Converting a SecretKey to String and back again

    There are many (hundreds?) of Java tutorials on the Internet that step through encrypting/decrypting using a generated key. Have you completed any of those successfully?

    Yes, you can save that key to a file and use it later. There are some tutorials that go into that detail, all the while warning that that is not a proper way to do encryption. Can you not find any of the latter type?

    Edit: You might also find this discussion useful.

  6. #6
    Member
    Join Date
    Oct 2013
    Posts
    77
    Thanks
    55
    Thanked 0 Times in 0 Posts

    Default Re: Converting a SecretKey to String and back again

    Quote Originally Posted by GregBrannon View Post
    There are many (hundreds?) of Java tutorials on the Internet that step through encrypting/decrypting using a generated key. Have you completed any of those successfully?
    I've looked through a number of tutorials throughout the past two weeks, and in every case there was something that ended up not working. Either it was missing code from the tutorial so it wasn't entirely complete, or it wasn't explanatory enough and I didn't get it to work for that reason. I have found one example though which does work with encrypting and decrypting, which is the one I'm using now, but they never explained how to store or load the key for it, and the method they use is different from pretty much every guide which offers an explanation of how to store/read a key. Most guides assume you use AES, but the one I'm using is called "PBEWithMD5AndDES".



    Quote Originally Posted by GregBrannon View Post
    Yes, you can save that key to a file and use it later. There are some tutorials that go into that detail, all the while warning that that is not a proper way to do encryption. Can you not find any of the latter type?
    I've found several that uses AES, but I haven't found any working encryption/decryption example which uses it.

    Quote Originally Posted by GregBrannon View Post
    Edit: You might also find this discussion useful.
    Sadly I have already been to that link several times in attempt to solve the problem, to no avail. =/

  7. #7
    Member
    Join Date
    Oct 2013
    Posts
    77
    Thanks
    55
    Thanked 0 Times in 0 Posts

    Default Re: Converting a SecretKey to String and back again

    After working with the code further, and doing even more searching, I finally found an example that works. I'll see if I can dig into it and get a better understanding of it now that it's finally working, only took about two weeks. ^^

    In case anyone's interested in using it:
    Java : Encryption and Decryption of Data using AES algorithm with example code | Code 2 Learn

    package (insertPackageName);
     
    import java.security.*;
     
    import javax.crypto.*;
    import javax.crypto.spec.SecretKeySpec;
     
    import sun.misc.*;
     
    public class Encryption {
     
         private static final String ALGO = "AES";
        private static final byte[] keyValue = 
            new byte[] { 'T', 'h', 'e', 'B', 'e', 's', 't',
     
    'S', 'e', 'c', 'r','e', 't', 'K', 'e', 'y' };
     
     
    @SuppressWarnings("restriction")
    public String encrypt(String Data) throws Exception {
            Key key = generateKey();
            Cipher c = Cipher.getInstance(ALGO);
            c.init(Cipher.ENCRYPT_MODE, key);
            byte[] encVal = c.doFinal(Data.getBytes());
            String encryptedValue = new BASE64Encoder().encode(encVal);
            return encryptedValue;
        }
     
        @SuppressWarnings("restriction")
    	public String decrypt(String encryptedData) throws Exception {
            Key key = generateKey();
            Cipher c = Cipher.getInstance(ALGO);
            c.init(Cipher.DECRYPT_MODE, key);
            byte[] decordedValue = new BASE64Decoder().decodeBuffer(encryptedData);
            byte[] decValue = c.doFinal(decordedValue);
            String decryptedValue = new String(decValue);
            return decryptedValue;
        }
        private static Key generateKey() throws Exception {
            Key key = new SecretKeySpec(keyValue, ALGO);
            return key;
    }
     
    }

Similar Threads

  1. vertical, front to back and string into decimal
    By arl13i1 in forum What's Wrong With My Code?
    Replies: 1
    Last Post: September 3rd, 2013, 06:15 PM
  2. Replies: 6
    Last Post: June 3rd, 2013, 04:57 AM
  3. Converting a String to an Int? Is it possible?
    By Gravity Games in forum Java Theory & Questions
    Replies: 2
    Last Post: July 14th, 2012, 11:21 PM
  4. How to change a String value into a number and then back into a String.
    By javapenguin in forum What's Wrong With My Code?
    Replies: 5
    Last Post: November 18th, 2011, 12:43 PM
  5. Converting to String
    By darek9576 in forum Object Oriented Programming
    Replies: 1
    Last Post: March 13th, 2010, 05:09 PM