Reputation: 31
I have two classes named encryption.java and decryption.java. I want encrypt a text file using the encrypt.java class and decrypt from decrypt.java class. I can encrypt the text file successfully, but not able to decrypt it in same way. Can anyone tell me why not?
This is encrypt.java:
public class Encrypt{
public static void main(String[] args) throws Exception {
String FileName = "D:/ashok/normal.txt";
String FileName1 = "D:/ashok/encrypted.txt";
KeyGenerator KeyGen = KeyGenerator.getInstance("AES");
KeyGen.init(128);
SecretKey SecKey = KeyGen.generateKey();
Cipher AesCipher = Cipher.getInstance("AES");
byte[] cipherText = Files.readAllBytes(Paths.get(FileName));
AesCipher.init(Cipher.ENCRYPT_MODE, SecKey);
byte[] byteCipherText = AesCipher.doFinal(cipherText);
Files.write(Paths.get(FileName1), byteCipherText);
}
This is my decrypt.java class:
class decrypt{
public static void main(String[] args) {
try {
String FileName1 = "D:/ashok/encrypted.txt";
String FileName2 = "D:/ashok/decrypted.txt";
KeyGenerator KeyGen = KeyGenerator.getInstance("AES");
KeyGen.init(128);
SecretKey SecKey = KeyGen.generateKey();
Cipher AesCipher = Cipher.getInstance("AES");
byte[] cipherrText = Files.readAllBytes(Paths.get(FileName1));
AesCipher.init(Cipher.DECRYPT_MODE, SecKey);
byte[] bytePlainText = AesCipher.doFinal(cipherrText);
Files.write(Paths.get(FileName2), bytePlainText); }}
and getting error when decrypt class runs, like this
javax.crypto.BadPaddingException: Given final block not properly padded
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:811)
at com.sun.crypto.provider.CipherCore.doFinal(CipherCore.java:676)
at com.sun.crypto.provider.AESCipher.engineDoFinal(AESCipher.java:313)
at javax.crypto.Cipher.doFinal(Cipher.java:2086)
at decryption.main(decryption.java:79)
Upvotes: 0
Views: 1601
Reputation: 158
Before anything, I think that you should read more about symmetric cryptography here. As you will note, one of the main features of symmetric cryptography is that they same key is used to encrypt and decrypt. In contrast, asymmetric cryptography (or Public key cryptography link) uses a pair of keys: one to encrypt and the other one to decrypt.
Thus, your problem is that you should persist the SecretKey SecKey
. For instance, you can persist the secret key in a separate file. To do this, you need (a) the byte array (the key), and (b) the algorithm. An example of how to do this on the Encrypt side could be:
String serializedSecKey = new String(Base64.encodeBase64(masterSecretKey.getEncoded())) + ";" + masterSecretKey.getAlgorithm() storeToFile(filename, serializedSecKey);
The Base64.encodeBase64()
is from org.apache.commons.codec.binary.Base64;
. Note that I have added a delimiter between the key and its algorithm to facilitate the parsing.
Then, in your Decrypt side you could parse the file containing the information regarding the secret key. An example to reconstruct the key would be:
String serializedSecKey = // obtain the string from the file String [] key = serializedSecKey.split(";"); byte[] keyBytes = Base64.decodeBase64(key[0]); String algorithm = key[1]; SecretKey secKey = new SecretKeySpec(keyBytes, algorithm);
And the obtained secKey
would be able to decrypt your message.
Finally, note that this might not be the best way to persist a secret key. There are much better options such as KeyStores that make all this sharing much easier.
Upvotes: 0
Reputation: 434
You need to store this SecretKey SecKey = KeyGen.generateKey();
value and share it between Encrypt and Decrypt classes.
So basically you have to use the same SecKey on both encryption and decryption processes.
Upvotes: 1
Reputation: 916
You generate the key used for encryption using SecretKey SecKey = KeyGen.generateKey()
, which is fine, but when you decrypt you try to use a new key, instead of the one you used to encrypt the text. You need to save your key so you can use it for decrypting.
Upvotes: 1