File Encryption and Decryption

How to encrypt and decrypt file in java  using RSA (public key,private key)and AES algorithms.I want to upload encrypted file to server and clients can  download this file in decrypted format.
spectrumsofttechAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

CEHJCommented:
Why not upload with https ? - it would be encrypted automatically. The receiving end would receive plaintext, but then that end can decrypt it anyway (by the sounds of things)
0
spectrumsofttechAuthor Commented:
In my application I want to encrypt file before upload to cloud , I used AES algorithm for file encryption and RSA for  encrypting AES Symmetric key .but I got an Error.
javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes
      at com.sun.crypto.provider.RSACipher.a(DashoA13*..)
      at com.sun.crypto.provider.RSACipher.engineDoFinal(DashoA13*..)
      at javax.crypto.Cipher.doFinal(DashoA13*..)
      at EncryptionDecryption.EncryptionUtil.encrypt(EncryptionUtil.java:87)
      at EncryptionDecryption.EncryptionUtil.main(EncryptionUtil.java:144)
java.lang.IllegalArgumentException: Null input buffer
      at javax.crypto.Cipher.doFinal(DashoA13*..)
      at EncryptionDecryption.EncryptionUtil.decrypt(EncryptionUtil.java:102)
      at EncryptionDecryption.EncryptionUtil.main(EncryptionUtil.java:149)
java.lang.NullPointerException
      at java.lang.String.<init>(String.java:593)
      at EncryptionDecryption.EncryptionUtil.decrypt(EncryptionUtil.java:108)
      at EncryptionDecryption.EncryptionUtil.main(EncryptionUtil.java:149)
0
CEHJCommented:
You'll need to post your code
0
Introduction to Web Design

Develop a strong foundation and understanding of web design by learning HTML, CSS, and additional tools to help you develop your own website.

spectrumsofttechAuthor Commented:
package EncryptionDecryption;
import java.io.BufferedInputStream;

public class EncryptionUtil {

  public static final String ALGORITHM = "RSA";

   public static final String PRIVATE_KEY_FILE = "private.txt";

  public static final String PUBLIC_KEY_FILE = "public.txt";

  public static void generateKey() {
    try {
      final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM);
      keyGen.initialize(1024);
      final KeyPair key = keyGen.generateKeyPair();

      File privateKeyFile = new File(PRIVATE_KEY_FILE);
      File publicKeyFile = new File(PUBLIC_KEY_FILE);

      // Create files to store public and private key
      if (privateKeyFile.getParentFile() != null) {
        privateKeyFile.getParentFile().mkdirs();
      }
      privateKeyFile.createNewFile();

      if (publicKeyFile.getParentFile() != null) {
        publicKeyFile.getParentFile().mkdirs();
      }
      publicKeyFile.createNewFile();

      // Saving the Public key in a file
      ObjectOutputStream publicKeyOS = new ObjectOutputStream(
          new FileOutputStream(publicKeyFile));
      publicKeyOS.writeObject(key.getPublic());
      System.out.println("public"+key.getPublic().getEncoded());
      publicKeyOS.close();

      // Saving the Private key in a file
      ObjectOutputStream privateKeyOS = new ObjectOutputStream(
          new FileOutputStream(privateKeyFile));
      privateKeyOS.writeObject(key.getPrivate());
      System.out.println("private"+key.getPrivate().getEncoded());
      //System.out.println(key.getPrivate());
      privateKeyOS.close();
    } catch (Exception e) {
      e.printStackTrace();
    }

  }

  public static boolean areKeysPresent() {

    File privateKey = new File(PRIVATE_KEY_FILE);
    File publicKey = new File(PUBLIC_KEY_FILE);

    if (privateKey.exists() && publicKey.exists()) {
      return true;
    }
    return false;
  }

  public static byte[] encrypt(byte[]bs, PublicKey key) {
    byte[] cipherText = null;
    try {
      // get an RSA cipher object and print the provider
      final Cipher cipher = Cipher.getInstance(ALGORITHM);
      // encrypt the plain text using the public key
      cipher.init(Cipher.ENCRYPT_MODE, key);
      cipherText = cipher.doFinal(bs);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return cipherText;
  }

  public static String decrypt(byte[] text, PrivateKey key) {
    byte[] dectyptedText = null;
    try {
      // get an RSA cipher object and print the provider
      final Cipher cipher = Cipher.getInstance(ALGORITHM);

      // decrypt the text using the private key
      cipher.init(Cipher.DECRYPT_MODE, key);
      dectyptedText = cipher.doFinal(text);

    } catch (Exception ex) {
      ex.printStackTrace();
    }

    return new String(dectyptedText);
  }

  public static void main(String[] args)throws IOException {
	 
	 
    try {
   	
        generateKey();
        File f=new File("test.txt"); //file is to encrypt
        byte[] contents = new byte[(int)f.length()];
        BufferedInputStream bis = null;
        try
        {
            bis = new BufferedInputStream(new FileInputStream(f));
            DataInputStream dis = new DataInputStream(bis);
            dis.readFully(contents);
        }
        finally
        {
            if(bis != null)
            {
                bis.close();
            }
        }           
        

     // final String originalText = "Text to be encrypted";
     

      // Encrypt the string using the public key
      ObjectInputStream  inputStream = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
      final PublicKey publicKey = (PublicKey) inputStream.readObject();
      final byte[] cipherText = encrypt(contents, publicKey);
      inputStream.close();
      // Decrypt the cipher text using the private key.
      ObjectInputStream inputStream1 = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
      final PrivateKey privateKey = (PrivateKey) inputStream1.readObject();
      final String plainText = decrypt(cipherText, privateKey);
      
      // Printing the Original, Encrypted and Decrypted Text
     
      System.out.println("Original Text: " + contents.toString());
      System.out.println("Encrypted Text: " +cipherText);
      System.out.println("Decrypted Text: " + plainText);
      inputStream.close();
      inputStream1.close();
      
    } catch (Exception e) {
      e.printStackTrace();
    }
    finally
    {
    	
    }
    
    }
  }

Open in new window

0
spectrumsofttechAuthor Commented:
I have genrated public and private key using RSA algorithm.I want To store these key values in database. how to to store these values. I have used this code. for key generation
KeyPairGenerator pairgen = KeyPairGenerator.getInstance("RSA");
     SecureRandom random = new SecureRandom();
     pairgen.initialize(KEYSIZE, random);
     KeyPair keyPair = pairgen.generateKeyPair();
    byte[] publickey=keyPair.getPublic().getEncoded();
 
    //byte[] privatekey=keyPair.getPrivate().getEncoded();
0
CEHJCommented:
That's not the code you're running (it wouldn't compile)

Please use code tags when posting code
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
The problem is that you are trying to encrypt/decrypt the input data DIRECTLY with the RSA key pair. As you mention in the original question, you should be encrypting using something like AES and then you can encrypt the AES key using RSA, but then in the code you have nothing to do with AES at all.

The exception message is pretty self explanatory, "...Data must not be longer than 117 bytes..." and that is because that is the limits of RSA encryption. It is only intended to be able to encrypt a small amount of information. And that is why AES/DES are used because there are no such limits.

How do combine both of these to achieve what you want? At a high level, the idea is... generate a random key and encrypt the input file with this key using AES/DES. Then encrypt the KEY using your RSA public key similar to how you are already doing this, as this key will be less than 117 bytes long. You send both the AES encrypted file and the RSA encrypted key to "the other side".

Then the decrpytion is just a reverse of this, using the RSA private key you can recover the AES key and you then use that to decrypt the original file.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
spectrumsofttechAuthor Commented:
I want to send encrypted key to client via email for  file decryption .But this is a 64 length byte array.How to send these byte array? Is any way to convert these byte array into small length String and convert to back.
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Generally you would use a base64 encoding for this. There are a number of libraries available for doing this and also a number of ways in standard JDK but the one that I generally use is...

http://docs.oracle.com/javaee/6/api/javax/xml/bind/DatatypeConverter.html

Look in particular at the static "parseBase64Binary" and "printBase64Binary" methods for converting between byte[] and their String representations.
0
CEHJCommented:
I want to send encrypted key to client via email for  file decryption .
Why would you send a method for securing data by an insecure method?
0
spectrumsofttechAuthor Commented:
In my application the user can upload file to cloud in encrypted form.after uploading file the user send key to the data access member for file decryption when they downloading that file.The key Distribution is via Email..
0
CEHJCommented:
It would probably be marginally safer to send the key through the post. Suffice it to say, it's not secure at all.
What you should be doing is encrypting the file with the public key of the intended recipient where possible.
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
@CEHJ,

spectrum could be a little bit more explicit in how he is wording the issue, but what he is doing is fine. He said that he wants to send the "encrypted" key via email. This is ok because this is the RSA public key encrypted version of the randomly generated AES key, ie. only the valid recipient who holds the correct private key can decrypt this key sent via email and make any use of it, decrypting the actual file.

What you should be doing is encrypting the file with the public key
This is the heart of the problem that we were dealing with above. You CAN'T directly encrypt the file using RSA public key encryption, as you are limited by the length of the input, ie. 117 bytes is not a lot, the file is likely to be much longer than that.
0
CEHJCommented:
This is ok because this is the RSA public key encrypted version of the randomly generated AES key,
My apologies - i thought we'd somehow moved into discussing symmetric cryp only

You CAN'T directly encrypt the file using RSA public key encryption, as you are limited by the length of the input, ie. 117 bytes is not a lot, the file is likely to be much longer than that.
Not sure why you say that. There's no limit on the size of the plaintext. An example of RSA PKI:

http://javadigest.wordpress.com/2012/08/26/rsa-encryption-example/
0
mccarlIT Business Systems Analyst / Software DeveloperCommented:
Not sure why you say that. There's no limit on the size of the plaintext.
You might want to double check that ;)

Actually, funny you picked that example as it is the basis for the OP's code posted above. I'm assuming that you ran the code and confirmed that it runs as intended. However, note the input plaintext defined on this line towards the end of the example...
final String originalText = "Text to be encrypted ";

Open in new window

It's obviously much less than 117 bytes long. Now just copy & paste the string content at least 6 or so more times so that it IS long than 117 bytes and run the code again. Basically the same exceptions as the posted result at the top of this thread.
0
CEHJCommented:
You might want to double check that ;)
OK, i've done that and it would seem that there is a natural limit. This could be circumvented by careful choice of the read buffer size and padding but afaik it's not really good practice to do this
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Java

From novice to tech pro — start learning today.