1

so I'm trying to encrypt a file thats created when the user types something and right after the encryption I want to decrypt the file. The file that the user created and the encryption file are created without an issue, but when I open the encrypted file its blank which I think is wrong since it should have some gibberish written on it.

package br.com.rsa;

import java.security.*;
import java.io.*;
import java.util.*;
import javax.crypto.*;

public class Geracao {



public static void main(String[] args) throws IOException {

    //Gerando um arquivo que será encriptado e descriptografado.
    Scanner entrada1 = new Scanner(System.in);

    System.out.println("Digite qualquer coisa: ");
    String entrada = entrada1.nextLine();

    System.out.println("Arquivo criado.");

    FileOutputStream saida = new FileOutputStream("arquivo.txt");
    PrintStream imprimir = new PrintStream(saida);
    System.setOut(imprimir);
    System.out.println(entrada);
    saida.close();

    //Gerando as chaves publica e privada.
    try {       
    KeyPairGenerator chave = KeyPairGenerator.getInstance("RSA");
    chave.initialize(1024);

    KeyPair chaves = chave.generateKeyPair();

    PrivateKey privada = chaves.getPrivate();
    PublicKey publica = chaves.getPublic();

    Base64.Encoder cripto = Base64.getEncoder();

    System.out.println("Chave privada: " + cripto.encodeToString(privada.getEncoded()));
    System.out.println("");
    System.out.println("Chave publica: " + cripto.encodeToString(publica.getEncoded()));
    System.out.println("");


        //Salvando as chaves publica e privada.
        try (FileOutputStream s_prv = new FileOutputStream("privada" + ".key")){

            s_prv.write(chaves.getPrivate().getEncoded());

        }

        try (FileOutputStream s_pub = new FileOutputStream("publica" + ".key")){

            s_pub.write(chaves.getPublic().getEncoded());
        }

        Criptografar(chaves, null);
        //Descriptografar(chaves, null);
    }

    //Qualquer erro dentro da geração das chaves
    catch (Exception e){

        System.out.println(e);
    }
}

//TODO - Comentario
 static private void processFile(Cipher cifra, InputStream entrada_arq_c, OutputStream saida_arq_c){
       try {
        byte[] ibuf = new byte[1024];
        int len;
        while ((len = entrada_arq_c.read(ibuf)) != -1) {
            byte[] obuf = cifra.update(ibuf, 0, len);
            if ( obuf != null ) saida_arq_c.write(obuf);
        }
        byte[] obuf = cifra.doFinal();
        if ( obuf != null ) saida_arq_c.write(obuf);
       }
      catch(Exception e) {

          System.out.println("Problema no manuseio do arquivo.");
      }
}

//Metodo para criptografar.
 static private void Criptografar(KeyPair chaves, Cipher ci){
    try {
        PublicKey publica = chaves.getPublic();
        Cipher cifra = Cipher.getInstance("RSA");
        cifra.init(Cipher.ENCRYPT_MODE, publica);

        FileInputStream entrada_arq_c = new FileInputStream("arquivo.txt");
        FileOutputStream saida_arq_c = new FileOutputStream("criptografado.txt");
        processFile(ci, entrada_arq_c, saida_arq_c);

    }
    catch(Exception e){

        System.out.println("Erro ao criptografar.");
    }
}

//Metodo para descriptografar.
 static private void Descriptografar(KeyPair chaves, Cipher ci){

    try {
        PrivateKey privada = chaves.getPrivate();
        Cipher cifra = Cipher.getInstance("RSA");
        cifra.init(Cipher.DECRYPT_MODE, privada);

        FileInputStream entrada_arq_c = new FileInputStream("criptografado.txt");
        FileOutputStream saida_arq_c = new FileOutputStream("descriptografado.txt");
        processFile(ci, entrada_arq_c, saida_arq_c);
    }
    catch(Exception e){

        System.out.println("Erro ao descriptografar.");
    }
  }
}
10
  • You say that the encrypted file is "created without an issue", but also say that "when I open the encrypted file its blank". Is the encrypted file is genuinely empty (in which case there was a problem creating it), or does the encrypted file contain data, but is shown as empty when it is opened? How are you opening the encrypted file to see that it is blank? Is the size of the encrypted file > zero bytes? Commented Nov 12, 2018 at 1:38
  • saida.close(); you're closing the underlying stream and then trying to write to it through System.out methods. I'm not sure what you're trying to do there. Commented Nov 12, 2018 at 1:39
  • @skomisa yes, the file is created but the size of it is 0 bytes. In the other hand, the file that the user created is bigger than 0. Commented Nov 12, 2018 at 2:19
  • @JamesKPolk This one is because if I didnt write it, the whole System.out methods would be written in the file that the user created preventing the encrypted file from being created. Commented Nov 12, 2018 at 2:19
  • @Baltazar OK. In that case you might want to clarify the situation in your question since your statement that the encrypted file is "created without an issue" is misleading. Although you might not be receiving any error, there is obviously some problem when creating the encrypted file, right? Commented Nov 12, 2018 at 2:24

1 Answer 1

2

Update:

RSA is not meant to encrypt large amounts of data. In this case, with a 1024 bit RSA key and padding that defaults to PKCS#1 v1.5, he cannot encrypt more than 117 bytes of data. – James K Polk


There are a lot of issues here.
First, you set System.out to new stream and close it. As a result you cannot see any response from your application.

Solution 1: keep default output stream and set it back

PrintStream defaultOutStream = System.out;
PrintStream imprimir = new PrintStream(saida);
System.setOut(imprimir);
System.out.println(entrada);
saida.close();
System.setOut(defaultOutStream);

Solution 2: write to file in different way, for example

try (FileOutputStream saida = new FileOutputStream("arquivo.txt");){
    saida.write(entrada.getBytes(Charset.forName("UTF-8")));
} catch (Exception e){
    e.printStackTrace();
}

Second, you have an exception. You will see "Problema no manuseio do arquivo." in you console after fixing first issue. But it is not helpful without stack trace. You need to update your catch block to print the cause of the exception. For example:

catch(Exception e) {
    e.printStackTrace();
    System.out.println("Problema no manuseio do arquivo.");
}

After it you will find in console the name of the exception and the the number of the line where it occurs. This is a root cause of why your output file is empty.


Before reading further, try to find how to fix nullpointer and what causes it. Practice debugging! put break point on the line which causing nullpointer.

First, you are calling constructor with Cipher as null:

Criptografar(chaves, null);

Next, you are creating correct cipher, but calling process function with old one which value is still null:

static private void Criptografar(KeyPair chaves, Cipher ci){
    try {
        PublicKey publica = chaves.getPublic();
        Cipher cifra = Cipher.getInstance("RSA");
        cifra.init(Cipher.ENCRYPT_MODE, publica);
        FileInputStream entrada_arq_c = new FileInputStream("arquivo.txt");
        FileOutputStream saida_arq_c = new FileOutputStream("criptografado.txt");
        processFile(ci, entrada_arq_c, saida_arq_c);
    }
    catch(Exception e){
        System.out.println("Erro ao criptografar.");
    }
}

One of the solution is to just call function with correct arguments: processFile(cifra, entrada_arq_c, saida_arq_c);

Few suggestions:

  • you are not using Cipher parameter in Criptografar constructor, remove it
  • print stack traces in all catch blocks
Sign up to request clarification or add additional context in comments.

6 Comments

Another problem is that RSA is not meant to encrypt large amounts of data. In this case, with a 1024 bit RSA key and padding that defaults to PKCS#1 v1.5, he cannot encrypt more than 117 bytes of data.
Thank you for the info! Didn't know and tested just on "Boom"
Nice answer.. just adding - correct approach to use RSA is encrypt data using a symmetric cipher with a random key (e. g. AES, 3DES, Salsa,..) and then the symmetric key is encrypted using RSA
@uli Thank you very much! It worked as expected! Thank you so much!
@JamesKPolk Thank you for the addition, this whole thing is just as a personal project since the teacher was doing the same thing on the ubuntu terminal and I was trying to experiment with it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.