读取RSA密钥文件触发流关闭异常,求技术排查方案
解决RSA密钥读取时的Stream closed错误
看起来你遇到的问题主要是由文件写入不完整、资源路径不匹配和异常处理不规范这几个点导致的,我来一步步帮你修复:
1. 修复文件写入时的流关闭问题
你的FileSave方法没有关闭ObjectOutputStream,这会导致写入的模和指数数据没有真正刷新到硬盘文件中,文件内容是空的或者不完整。当读取这样的文件时,ObjectInputStream初始化时就会触发Stream closed错误。
修改后的FileSave方法:
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); out.flush(); // 确保数据写入到缓冲区 }catch(IOException e){ e.printStackTrace(); // 打印异常,方便排查问题 } finally { // 必须关闭流,释放资源并确保数据写入硬盘 if(out != null){ try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } }
2. 修正密钥文件的读取路径
你用getResourceAsStream读取类路径下的资源,但密钥文件是保存到当前工作目录(比如你的IDE项目根目录),这两个位置不匹配,导致InputStream无法正确读取到文件,进而触发流关闭的错误。
修改ReadKey方法,改用FileInputStream读取当前目录的密钥文件:
PublicKey ReadKey(String filePath) throws IOException{ PublicKey publicKey = null; // 改用FileInputStream读取当前工作目录的文件 InputStream in = new FileInputStream(filePath); 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 (ClassNotFoundException | NoSuchAlgorithmException | InvalidKeySpecException e){ // 捕获具体异常并打印,不要吞掉错误 e.printStackTrace(); }finally{ // 关闭输入流,避免资源泄漏 try { if(input != null) input.close(); if(in != null) in.close(); } catch (IOException e) { e.printStackTrace(); } } return null; }
然后修改Encrypt方法中的调用路径:
PublicKey publicKey = ReadKey("public.key"); // 直接读取当前目录的文件
3. 增加空值检查,避免后续错误
在Encrypt方法中,要先检查读取到的公钥是否为null,避免用无效的公钥初始化Cipher:
public byte[] Encrypt(byte[] data) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IOException, BadPaddingException, IllegalBlockSizeException{ PublicKey publicKey = ReadKey("public.key"); if(publicKey == null){ throw new InvalidKeyException("Failed to load public key. Check if the key file exists and is correctly generated."); } Cipher cipher = Cipher.getInstance("RSA"); cipher.init(Cipher.ENCRYPT_MODE, publicKey); byte[] cipherData = cipher.doFinal(data); return cipherData; }
额外建议
- 确保
KeyStorage方法已经被正确调用过,生成了public.key和private.key文件在当前工作目录下; - 不要随意吞掉异常(比如原来的空catch块),打印堆栈信息能帮你快速定位问题;
- 对于RSA加密,注意数据长度限制(RSA加密的最大明文长度是密钥长度/8 - 11,比如2048位密钥最多加密245字节),如果要加密长文本,建议结合对称加密(比如AES),用RSA加密AES密钥。
内容的提问来源于stack exchange,提问作者FocusedTerror96
相关产品推荐
相关产品推荐

