Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do Encryption and Decryption of a File?

I use CipherOutputStream to encryption and decryption file in java, but input file > 117 byte cannot encryption. I use RSA algorithm public key lenght 1024 byte.

cipher.init(Cipher.ENCRYPT_MODE, secKey);

String cleartextFile = "cleartext.txt";
String ciphertextFile = "ciphertextSymm.txt";

FileInputStream fis = new FileInputStream(cleartextFile);
FileOutputStream fos = new FileOutputStream(ciphertextFile);
CipherOutputStream cos = new CipherOutputStream(fos, cipher);

byte[] block = new byte[8];
int i;
while ((i = fis.read(block)) != -1) {
      cos.write(block, 0, i);
}
cos.close();

How to encryption input file length > 117 byte?

like image 818
Nhu Nguyen Avatar asked May 14 '13 15:05

Nhu Nguyen


People also ask

How encryption and decryption is done?

A symmetric key is used during both the encryption and decryption processes. To decrypt a particular piece of ciphertext, the key that was used to encrypt the data must be used. The goal of every encryption algorithm is to make it as difficult as possible to decrypt the generated ciphertext without using the key.

Is there a way to decrypt files?

Right-click on the encrypted file and select Properties. In the General tab, select Advanced. Now, uncheck the Encrypt contents to secure data radio box and click on OK. You'll see another dialog box asking if you want to Apply changes to this folder or Apply changes to this folder, subfolders and files.

How do I decrypt a single file?

Launch the File Decryption utility (ZESDecrypt.exe). Make sure the Choose a File option is selected. In the Source field, click Browse, select the password-encrypted file, then click Open. In the Destination field, click Browse, select a folder in which to place the decrypted file, then click OK.


1 Answers

You cannot encrypt a file using RSA because RSA (well, to be more precise, the implementation of RSA in Java) does not let you encrypt more data than the length of the key. For a 1024 bits key, you can only encrypt 1024 bits that is to say 128 bytes (actually a bit less for padding reasons).

In all cases, it is bad practice to encrypt a large piece of data using a public-key algorithm (asymmetric cryptography) for two main reasons.

  1. The is no practical, appropriate and secure cryptographic mode/padding to encrypt large amounts of data using RSA (ie it is not really secure to do that).

  2. Public-key algorithms require a large key to be secure (1024 bits, 2048 bits) and are therefore much slower than symmetric-key algorithms (which only require 128 to 256 bits keys to be secure).

If you want more details on why you should not use solely RSA to encrypt large amounts of data, see these two great stacktexchange posts :

  • How can I use asymmetric encryption, such as RSA, to encrypt an arbitrary length of plaintext?
  • Is RSA in a ECB-like-mode safe for bulk encryption?

If you want to encrypt a large amount of data, the standard way to proceed is to generate a session key (a cryptographically secure random number used once). You encrypt the session key with the public key. Then you encrypt the file (the large amount of data) with a symmetric algorithm (such AES) using the unencrypted session key. You then store the encrypted session key and the encrypted data altogether in the final file. That's the way PGP (or GnuPG) proceeds when it sends an encrypted mail. SSL/TLS also works in a similar way.

Lastly, properly using cryptography is complicated (pretty much anything can create a security flaw : encryption modes, padding, etc...) so I would advise you to be very careful and make sure your code is going to be reviewed by someone knowledgeable in crypto matters.

Here is a piece of code that shows the general process :

// 1. Generate a session key
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(128)
SecretKey sessionKey = keyGen.generateKey();

// 2. Encrypt the session key with the RSA public key
Cipher rsaCipher = Cipher.getInstance("RSA");
rsaCipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey)
byte[] encryptedSessionKey = rsaCipher.doFinal(sessionKey.getEncoded());

// 3. Encrypt the data using the session key (unencrypted)
Cipher aesCipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
aesCipher.init(Cipher.ENCRYPT_MODE, sessionKey); <-- sessionKey is the unencrypted
//                                                   session key.
// ... use aesCipher to encrypt your data

// 4. Save the encrypted data along with the encrypted 
// session key (encryptedSessionKey).
// PLEASE NOTE THAT BECAUSE OF THE ENCRYPTION MODE (CBC),
// YOU ALSO NEED TO ALSO SAVE THE IV (INITIALIZATION VECTOR).
// aesCipher.aesCipher.getParameters().
//     getParametersSpec(IvParameters.class).getIV();
like image 183
Xion345 Avatar answered Sep 29 '22 18:09

Xion345