5

My aim is to write a Java program to encrypt a text file (cipher text) using AES algorithm. And then, write another program to decrypt that encrypted file (cipher text) to get the plain text back. I want to use same key (same key, generate once, save it somewhere, and use it in both encryption and decryption program) for encryption and decryption process. If I generate key and do the encryption and decryption line by line in the same program then it works perfectly. Here is the working code snippet for that:

        String strDataToEncrypt = new String();
        String strCipherText = new String();
        String strDecryptedText = new String();

        KeyGenerator keyGen = KeyGenerator.getInstance("AES");
        keyGen.init(128);
        SecretKey secretKey = keyGen.generateKey();

        Cipher aesCipher = Cipher.getInstance("AES");
        aesCipher.init(Cipher.ENCRYPT_MODE,secretKey);

        strDataToEncrypt = "any text input";
        byte[] byteDataToEncrypt = strDataToEncrypt.getBytes();
        byte[] byteCipherText = aesCipher.doFinal(byteDataToEncrypt); 
        strCipherText = new BASE64Encoder().encode(byteCipherText);
        System.out.println("cipher text: " +strCipherText);
        aesCipher.init(Cipher.DECRYPT_MODE,secretKey,aesCipher.getParameters());
        byte[] byteDecryptedText = aesCipher.doFinal(new BASE64Decoder().decodeBuffer(strCipherText));
        strDecryptedText = new String(byteDecryptedText);
        System.out.println("plain text again: " +strDecryptedText);

But, I need to have two different programs (java files) for encryption and decryption. So, I have to somehow generate a key and save that somewhere. Then use the same key for both encryption and decryption program. How can I do that?

EDIT_1

KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128);
SecretKey secretKey = keyGen.generateKey();
byte[] encoded = secretKey.getEncoded(); 
System.out.println("key: "+encoded);// key: [B@52b2a2d8

I can get the encoded key value using the above program. But my question is how to generate the SecretKey using this value in my decryption program?

K M Rakibul Islam
  • 33,760
  • 12
  • 89
  • 110
  • 1
    You generated a key, what's stopping you from writing it to a file and then reading it in the second program? – Jim Garrison Nov 27 '13 at 04:19
  • The key is a `byte[]` for which the system uses `Object#toString()`, which just writes out the internal identity. You need to write the individual byte _values_ to a file, maybe converting them to hex first. – Jim Garrison Nov 27 '13 at 04:35

2 Answers2

18

Forgive me if I misunderstood your question but I believe you wish to reconstruct a SecretKey object from a existing key encoded in a byte array.

This can be performed simply by using the javax.crypto.spec.SecretKeySpec's constructor as such:

byte[] encoded = //Key data

SecretKey secretKey = new SecretKeySpec(encoded, "AES");

Since SecretKeySpec is a subclass of SecretKey no casting is needed. Should your encryption/decrption algorithm change please make sure to change the string literal used in the constructor AES to whatever algorithm you decided to use in the future.

initramfs
  • 8,275
  • 2
  • 36
  • 58
  • 1
    Thanks, i used Base64Coder to convert the key to Hex String and saved to preferences then retrieved the key and decoded it using Base64Coder and it worked perfectly. – Diljeet Mar 20 '15 at 19:50
1

Here's one way to print out the values in a byte[] array in hex:

byte[] a = {-120, 17, 42,121};
for (byte b : a)
{
    System.out.printf("%2X",b);
}
System.out.println();
Jim Garrison
  • 85,615
  • 20
  • 155
  • 190
  • I can use this too: Arrays.toString(byte[]) to get the content of the byte array. But, I am not sure how to initialize the SecretKey using this value. Still digging into it. – K M Rakibul Islam Nov 27 '13 at 04:55
  • If you use `Arrays.toString(byte[])` you will go through a byte-to-character encoding conversion that may not be reversible. – Jim Garrison Nov 27 '13 at 06:32
  • [`Arrays.toString(byte[])`](http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#toString(byte[])) is defined to produce a standard representation of the array which is very unlikely to change. However I agree that it's definitely not ideal for this purpose. @KeenLearner Consider hex or Base64 encoding if you need to represent the key in ASCII, and keep in mind that files can contain binary data. – ntoskrnl Nov 27 '13 at 12:47