在JAVA上使用RSA进行加密和解密的问题

时间:2018-11-12 01:18:57

标签: java encryption rsa

所以我想对用户输入内容时创建的文件进行加密,并且在加密之后我想解密该文件。用户创建的文件和加密文件都没有问题,但是当我打开加密文件时,我认为这是错误的,因为它上面写有一些胡言乱语。

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.");
    }
  }
}

1 个答案:

答案 0 :(得分:2)

更新:

  

RSA并非旨在加密大量数据。在这种情况下,   默认为PKCS#1 v1.5的1024位RSA密钥和填充,他不能   加密超过117个字节的数据。 – James K Polk


这里有很多问题。
首先,将System.out设置为新流并关闭它。结果,您看不到应用程序的任何响应。

解决方案1:保留默认输出流并将其设置回

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

解决方案2:例如,以不同的方式写入文件

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

第二,您有一个例外。您将看到“没有任何问题的arquivo”。修复第一个问题后在控制台中进行操作。但是,如果没有堆栈跟踪,它就没有帮助。您需要更新catch块以打印异常原因。例如:

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

在此之后,您将在控制台中找到异常的名称和发生异常的行号。这是导致输出文件为空的根本原因


在进一步阅读之前,请尝试查找如何修复nullpointer以及其原因。练习调试!将断点放在导致空指针的行上。

首先,您使用Cipher作为null来调用构造函数:

Criptografar(chaves, null);

接下来,您正在创建正确的密码,但是使用旧值仍为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.");
    }
}

解决方案之一是仅使用正确的参数调用函数:processFile(cifra, entrada_arq_c, saida_arq_c);

一些建议:

  • 您没有在Cipher构造函数中使用Criptografar参数,请将其删除
  • 在所有捕获块中打印堆栈跟踪