读取我的 public 和私钥文件时遇到问题
Having A problem with reading my public and private key files
我在加密 class 中有一个方法负责读取我的 RSA 密钥文件和相应的组件。为此,请将 InputStream
对象与 ObjectInputStream
对象一起使用。它们分别称为 in
和 input
。我的问题是我认为我可能对如何使用这些有错误的想法。当我尝试从我的加密方法中调用此 class 来加密一些二进制数据时,我的错误出现了。我会 link 在 ReadKey
和 Encrypt
方法下面。
两种方法:
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;
}
为了增加我的问题的背景,我将解释我如何使用它们。
我还有其他创建 public 和 RSA 私钥的方法。现在,我使用加密的这个程序是一个简单的消息传递程序,它通过套接字将消息从服务器发送到客户端。我想使用 RSA 整合端到端加密,这就是所有这些的用武之地。
当用户单击发送时我抓取输入的文本(保存为变量 message
)然后 运行 这一行 sendMessage(Encryption.Encrypt(Converter(message)));
它首先将字符串传递给我的转换器方法,该方法将我的消息从字符串到字节数组[]。然后将其交给我上面的加密方法。当我的加密方法调用 PublicKey publicKey = ReadKey("/public.key");
并且似乎是 ReadKey
方法中围绕此 ObjectInputStream input = new ObjectInputStream(new BufferedInputStream(in));
的问题时,就会发生错误。我对这个有点困惑,因为我对这些工具还比较陌生。我将 link 留给以下错误片段:
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.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()
编写 public 和私钥。然后,您可以使用相同的密钥工厂,但使用 X509EncodedKeySpec
回读 public 密钥和 PKCS8EncodedKeySpec
作为私钥。
请注意,您目前只是在编写私钥的模数和私钥指数。在实践中也写了中国剩余定理(CRT)参数,这些参数可以用来加速RSA私钥运算。
感谢您的帮助,我成功地创建了一种新算法,目前看起来可以正常工作。我会在下面 link 让我知道你的想法,对于变量名提前抱歉,我正在处理它。
/*
* 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, NoSuchAlgorithmException, NoSuchPaddingException, IOException, BadPaddingException, 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, NoSuchAlgorithmException, NoSuchPaddingException, IOException, BadPaddingException, IllegalBlockSizeException{
return decrypt(Base64.getDecoder().decode(data.getBytes()), getPrivateKey(base64PrivateKey));
}
}
我在加密 class 中有一个方法负责读取我的 RSA 密钥文件和相应的组件。为此,请将 InputStream
对象与 ObjectInputStream
对象一起使用。它们分别称为 in
和 input
。我的问题是我认为我可能对如何使用这些有错误的想法。当我尝试从我的加密方法中调用此 class 来加密一些二进制数据时,我的错误出现了。我会 link 在 ReadKey
和 Encrypt
方法下面。
两种方法:
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;
}
为了增加我的问题的背景,我将解释我如何使用它们。
我还有其他创建 public 和 RSA 私钥的方法。现在,我使用加密的这个程序是一个简单的消息传递程序,它通过套接字将消息从服务器发送到客户端。我想使用 RSA 整合端到端加密,这就是所有这些的用武之地。
当用户单击发送时我抓取输入的文本(保存为变量 message
)然后 运行 这一行 sendMessage(Encryption.Encrypt(Converter(message)));
它首先将字符串传递给我的转换器方法,该方法将我的消息从字符串到字节数组[]。然后将其交给我上面的加密方法。当我的加密方法调用 PublicKey publicKey = ReadKey("/public.key");
并且似乎是 ReadKey
方法中围绕此 ObjectInputStream input = new ObjectInputStream(new BufferedInputStream(in));
的问题时,就会发生错误。我对这个有点困惑,因为我对这些工具还比较陌生。我将 link 留给以下错误片段:
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.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()
编写 public 和私钥。然后,您可以使用相同的密钥工厂,但使用 X509EncodedKeySpec
回读 public 密钥和 PKCS8EncodedKeySpec
作为私钥。
请注意,您目前只是在编写私钥的模数和私钥指数。在实践中也写了中国剩余定理(CRT)参数,这些参数可以用来加速RSA私钥运算。
感谢您的帮助,我成功地创建了一种新算法,目前看起来可以正常工作。我会在下面 link 让我知道你的想法,对于变量名提前抱歉,我正在处理它。
/*
* 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, NoSuchAlgorithmException, NoSuchPaddingException, IOException, BadPaddingException, 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, NoSuchAlgorithmException, NoSuchPaddingException, IOException, BadPaddingException, IllegalBlockSizeException{
return decrypt(Base64.getDecoder().decode(data.getBytes()), getPrivateKey(base64PrivateKey));
}
}