读取我的公钥和私钥文件时出现问题

问题描述

我在加密类中有一个方法,负责读取我的 RSA 密钥文件和相应的组件。为此,请使用带有 InputStream 对象的 ObjectInputStream 对象。它们分别称为 ininput。我的问题是我认为我可能对如何使用这些有错误的想法。当我尝试从我的加密方法调用这个类来加密一些二进制数据时,我的错误出现了。我将在 ReadKeyEncrypt 方法下方链接

两种方法

PublicKey  ReadKey(String File) throws IOException{
        PublicKey publicKey = null;
        InputStream in = Encryption.class.getResourceAsstream(File);
        
        ObjectInputStream input = new ObjectInputStream(new BufferedInputStream(in));
        try {
            BigInteger m = (BigInteger) input.readobject();
            BigInteger e = (BigInteger) input.readobject(); 
            RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m,e);
            KeyFactory fact = KeyFactory.getInstance("RSA");
            publicKey = fact.generatePublic(keySpec);
            return publicKey;
        }catch (Exception e){
        
        }finally{
            // input.close();
        }
    return null;
        
}



public byte[] Encrypt(byte[] data) throws InvalidKeyException,NoSuchAlgorithmException,NoSuchPaddingException,IOException,BadPaddingException,IllegalBlockSizeException{
        PublicKey publicKey = ReadKey("/public.key");
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE,publicKey);
        
        byte[] cipherData = cipher.doFinal(data);
        return cipherData;
}




为了添加到我的问题的上下文中,我将解释我如何使用这些。 我有其他方法可以创建公共和私人 RSA 密钥。现在我使用的这个加密程序是一个简单的消息传递程序,它通过套接字从服务器向客户端发送消息。我想结合使用 RSA 的端到端加密,这就是这一切的来源。 我在用户点击发送时抓取输入的文本(保存为变量 message),然后运行这一行 sendMessage(Encryption.Encrypt(Converter(message))); 它首先将字符串传递给我的转换器方法,该方法将我的消息从字符串转换为字节大批[]。然后将其交给我上面的加密方法。当我的加密方法调用 PublicKey publicKey = ReadKey("/public.key"); 时会发生错误,并且似乎是 ObjectInputStream input = new ObjectInputStream(new BufferedInputStream(in)); 方法中围绕此 ReadKey 的问题。我对这个有点困惑,因为我对这些工具比较陌生。我会留下指向以下错误片段的链接

java.io.IOException: Stream closed
    at java.base/java.io.BufferedInputStream.getinifOpen(BufferedInputStream.java:157)
    at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:244)
    at java.base/java.io.BufferedInputStream.read1(BufferedInputStream.java:284)
    at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:343)
    at java.base/java.io.ObjectInputStream$PeekInputStream.read(ObjectInputStream.java:2914)
    at java.base/java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2930)
    at java.base/java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3427)
    at java.base/java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:962)
    at java.base/java.io.ObjectInputStream.<init>(ObjectInputStream.java:405)
    at oserver.Encryption.ReadKey(Encryption.java:114)
    at oserver.Encryption.Encrypt(Encryption.java:133)
    at oserver.Server.jButton1ActionPerformed(Server.java:172)
    at oserver.Server$1.actionPerformed(Server.java:105)

我知道阅读很长很抱歉。任何帮助都会非常感谢,如果您需要更多信息,我对此没有任何问题。非常感谢:)

我如何存储我的密钥:

 public void KeyStorage() throws NoSuchAlgorithmException,InvalidKeySpecException{
        
        KeyFactory factory = KeyFactory.getInstance("RSA"); // creating a key factory object
        RSAPublicKeySpec publ = factory.getKeySpec(Pairs.getPublic(),RSAPublicKeySpec.class); // Creat a RSAPublicKeySpec object that allows us to translate between keys and there specification
        RSAPrivateKeySpec priv = factory.getKeySpec(Pairs.getPrivate(),RSAPrivateKeySpec.class); // Creat a RSAPublicKeySpec object that allows us to translate between keys and there specification
        try{
            FileSave("public.key",publ.getModulus(),publ.getPublicExponent()); // Saving the Exponent and Modulus to file public.key
            FileSave("private.key",priv.getModulus(),priv.getPrivateExponent()); // Saving the Exponent and Modulus to file private.key
        }catch(IOException e){
            // need to handle this error at some point
        }
    }
    
    public void FileSave(String fileName,BigInteger mod,BigInteger exp) throws IOException{
        
        ObjectOutputStream out = null;
            
        try{
            out = new ObjectOutputStream(new bufferedoutputstream(new FileOutputStream(fileName)));  
            out.writeObject(mod);
            out.writeObject(exp);
        }catch(IOException e){
            // need to handle this error at some point
        }
    }    


解决方法

直接的问题是您正在写入文件并从资源中读取。资源是包含在 Java 源文件中的只读文件(例如 GUI 应用程序中的图标)。

您绝对应该使用 key.getEncoded() 来编写公钥和私钥。然后,您可以使用相同的密钥工厂,但使用 X509EncodedKeySpec 读回公钥,使用 PKCS8EncodedKeySpec 读回私钥。

请注意,您目前只是在为私钥编写模数和私有指数。在实践中也写了中国剩余定理(CRT)参数,这些参数可以用来加速RSA私钥运算。

,

感谢您的所有帮助,我设法创建了一种新算法,目前看起来可以正常工作。我会在下面链接它,让我知道您的想法,并提前为变量名称道歉,我正在努力。

/*
 * To change this license header,choose License Headers in Project Properties.
 * To change this template file,choose Tools | Templates
 * and open the template in the editor.
 */
package oserver;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;


/**
 *
 * @author sgmud
 */
public class Encryption {
    
    
    public static PrivateKey privateKey;
    public static PublicKey publicKey;
    
    public void KeyGeneration() throws NoSuchAlgorithmException{
        KeyPairGenerator Generator = KeyPairGenerator.getInstance("RSA"); // Creat the Generator object with RSA
        Generator.initialize(1024); // Set the generator to make the 2048 bit key
        KeyPair Pair = Generator.genKeyPair(); // Generate the key pair
        publicKey = Pair.getPublic(); // Set the Public Key
        privateKey = Pair.getPrivate(); // Set the private Key
        
        System.out.println(Base64.getEncoder().encodeToString(publicKey.getEncoded()));
        System.out.println(Base64.getEncoder().encodeToString(privateKey.getEncoded()));

              
    }

    

    
    
 
    public void writeToFile(String filePath,byte[] key) throws IOException{
        File fileToWriteto = new File(filePath);
        fileToWriteto.getParentFile().mkdirs();
        FileOutputStream FoutputStream = new FileOutputStream(fileToWriteto);
        FoutputStream.write(key);
        FoutputStream.flush();
        FoutputStream.close();
        
    
    }
    
    
    
    
    
    
    
    
    
 

    
    
    
    public static PublicKey getPublicKey(String base64PublicKey){
        PublicKey publicKey = null;
        try{
            X509EncodedKeySpec KeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(base64PublicKey.getBytes()));
            KeyFactory Keyfact = KeyFactory.getInstance("RSA");
            publicKey = Keyfact.generatePublic(KeySpec);
            return publicKey;   
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (InvalidKeySpecException e) {
            e.printStackTrace();
        }
        return publicKey;
    }

    public byte[] Encrypt(String data,String publicKey) throws InvalidKeyException,NoSuchAlgorithmException,NoSuchPaddingException,IOException,BadPaddingException,IllegalBlockSizeException{
        
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE,getPublicKey(publicKey));
        return cipher.doFinal(data.getBytes());
}

 
 
    
    
    
    
    
    
    public static PrivateKey getPrivateKey(String base64PrivateKey){
        PrivateKey privateKey = null;
        PKCS8EncodedKeySpec keySpec = new  PKCS8EncodedKeySpec(Base64.getDecoder().decode(base64PrivateKey.getBytes()));
        KeyFactory Kfact = null;
        try{
            
            Kfact = Kfact.getInstance("RSA");
            
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace(); 
        }
        try{
            privateKey = Kfact.generatePrivate(keySpec);
        }catch(InvalidKeySpecException e){
            e.printStackTrace();
        }
        return privateKey;
    }
 
    public static String decrypt(byte[] data,PrivateKey privateKey) throws InvalidKeyException,IllegalBlockSizeException{
        
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE,privateKey);
        return new String(cipher.doFinal(data));
} 
    
    
    
    
    public static String Decrypt(String data,String base64PrivateKey) throws InvalidKeyException,IllegalBlockSizeException{
        return decrypt(Base64.getDecoder().decode(data.getBytes()),getPrivateKey(base64PrivateKey));
} 
    
    
    
 
    
    
    
    
    
       
        
}