Convert a file to encrypted file and decrypt it on server (Using Public key encryption)

1.6k views Asked by At

I am trying to encrypt/decrypt a file using RSA. But I can't see the data inside the file.

Here is the Code :

     // To encrypt a file 

  private static void encrypt(InputStream input, OutputStream output, PublicKey key)
        throws IOException, NoSuchAlgorithmException,   NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException     {
    final Cipher encrypt = Cipher.getInstance(ALGORITHM);
  // encrypt the plain text using the public key
         encrypt.init(Cipher.ENCRYPT_MODE, key);
        // encrypt.doFinal();
    output = new CipherOutputStream(output,encrypt);
    writeBytes(input, output, encrypt);
            output.close();
}


    // To decrypt  the file

private static void decrypt(InputStream input, OutputStream output, PrivateKey key)
        throws IOException,NoSuchAlgorithmException,InvalidKeyException,NoSuchPaddingException,BadPaddingException,IllegalBlockSizeException {
        final Cipher decrypt = Cipher.getInstance(ALGORITHM);

  // decrypt the text using the private key
  decrypt.init(Cipher.DECRYPT_MODE, key);
    input = new CipherInputStream(input, decrypt);
    writeBytes(input, output, decrypt);
            input.close();
}

// To write on the file from the inputstream

private static void writeBytes(InputStream input, OutputStream output, Cipher cipher)
        throws IOException, IllegalBlockSizeException,BadPaddingException {
    byte[] writeBuffer = new byte[512];
    int readBytes = 0;

    while ((readBytes = input.read(writeBuffer)) >= 0) {
                System.out.println(readBytes);




               // String text = input.read(writeBuffer);
               // cipher.doFinal();
                try{
                    System.out.println("Here");
        output.write(writeBuffer, 0, readBytes);
                }
                catch(Exception e){
                e.printStackTrace();
                }
    }

    output.close();
    input.close();
}

Main Function :

  // Check if the pair of keys are present else generate those.
  if (!areKeysPresent()) {
    // Method generates a pair of keys using the RSA algorithm and stores it
    // in their respective files
    generateKey();
  }

  final String originalText = "Text to be encrypted ";
  ObjectInputStream inputStream = null;

  String clearFile = "/UploadFile/Log.txt";      
  String encryptedFile = "/UploadFile/LogE.txt";      
  String decryptedFile = "/UploadFile/LogD.txt";

  // Encrypt the string using the public key
  inputStream = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE));
  final PublicKey publicKey = (PublicKey) inputStream.readObject();
 // final byte[] cipherText = encrypt(originalText, publicKey);

  encrypt(new FileInputStream(clearFile), new FileOutputStream(encryptedFile), publicKey);
  System.out.println("Successfully Encrypted");

  }
  // Decrypt the cipher text using the private key.
  inputStream = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE));
  final PrivateKey privateKey = (PrivateKey) inputStream.readObject();
 // final String plainText = decrypt(cipherText, privateKey);

  decrypt(new FileInputStream(encryptedFile), new FileOutputStream(decryptedFile), privateKey);
  System.out.println("Successfully Decrypted");


GenerateKey Function : 

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());
  publicKeyOS.close();

  // Saving the Private key in a file
  ObjectOutputStream privateKeyOS = new ObjectOutputStream(
      new FileOutputStream(privateKeyFile));
  privateKeyOS.writeObject(key.getPrivate());
  privateKeyOS.close();
} catch (Exception e) {
  e.printStackTrace();
}

  }

I am not getting any data in the encrypted as well as decrypted file.

clearFile is the original data file, encryptedFile is encrypted data, decryptedFile is decrypted data.

Please help, What I am missing here.

2

There are 2 answers

0
erickson On BEST ANSWER

You don't use RSA for data encryption. You use it to encrypt a symmetric key, and use a symmetric key to encrypt your data. Public key algorithms are for key transport or key agreement, not data.

You should use a CMS (S/MIME) or PGP library for your application.

2
Gari BN On

I don't know what is the size of the file you try to encrypt, but in RSA, you cannot encrypt too much data. It is bounded in the N parameter which is part of the key, so for sure your data should be shorter then the key. Maybe this is the problem.

Usually, you use public key encryption to encrypt a symmetric key (for example AES), then you encrypt the data with the encrypted symmetric key efficiently. This is called hybrid encryption.

I would recommend you to first try to use AES for encryption, and then to try and encrypt only the AES-key.