持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第3天,点击查看活动详情
今天在使用 hutool 工具时,通过以下代码创建一对 密钥(公钥和私钥):
KeyPair pair = SecureUtil.generateKeyPair("RSA");
PrivateKey aPrivate = pair.getPrivate();
PublicKey aPublic = pair.getPublic();
然后将 aPrivate 和 aPublic 转换成两个字符串,并通过 IO 流的方式将其保存到本地文件里:
writeDetails(Base64.encode(aPrivate.getEncoded()),Base64.encode(aPublic.getEncoded()));
public void writeDetails(String pri,String pub){
System.out.println(pri);
System.out.println(pub);
try(
Writer writerPri = new FileWriter("f:/private.txt");
Writer writerPub = new FileWriter("f:/public.txt");
){
writerPri.write(pri);
writerPub.write(pub);
} catch (IOException e) {
e.printStackTrace();
}
}
保存最终成功了!但是后面在进行 读取使用 的时候给抛出了异常:
InvalidKeySpecException: java.security.InvalidKeyException: IOException : DerInputStream.getLength(): lengthTag=105, too big.
抛出异常的代码:
public String[] getKey(){
String[] strings = new String[2];
try(
Reader readerPri = new FileReader(privateKeyUrl);
Reader readerPub = new FileReader(publicKeyUrl)
){
while(true){
char[] ch = new char[1024];
int read = readerPri.read(ch);
if(read == -1){
break;
}
strings[0] += new String(ch,0,read);
}
while(true){
char[] ch = new char[1024];
int read = readerPub.read(ch);
if(read == -1){
break;
}
strings[1] += new String(ch,0,read);
}
} catch (IOException e) {
e.printStackTrace();
}
return strings;
}
通过百度,发现好像是 maven 在进行编译时对文件里面进行了修改!也就是说密钥字符串前后有空格/换行/多余的字符(-----BEGIN RSA PRIVATE KEY-----这种)。
(但是我在自己的本地文件中并没有发现,可能是 maven 在编译的时候给我修改了吧,总之刚开始接触RSA ,对加密这一块基本都是空白。后序了解清楚了再来对这篇笔记进行整理。)
解决办法:
不使用 FileReader 来进行读取。更改为 BufferedReader(缓冲字符流) 来进行读取操作。 (这样做好像就可以去掉 开头的 BEGIN 和 末尾的 END)
public String[] getKey(){
String[] strings = new String[2];
try(
BufferedReader readerPri = new BufferedReader(new FileReader(privateKeyUrl));
BufferedReader readerPub = new BufferedReader(new FileReader(publicKeyUrl))
){
String readLine = null;
StringBuilder sb = new StringBuilder();
// 每次读取一行
while ((readLine = readerPri.readLine()) != null) {
sb.append(readLine);
}
// 将读取的第一个 钥匙 放到 数组 中
strings[0] = sb.toString();
// 将临时变量 sb 清空,用来存储 另一把钥匙
sb.delete(0,sb.length());
// 每次读取一行
while ((readLine = readerPub.readLine()) != null) {
sb.append(readLine);
}
// 将读取的第一个 钥匙 放到 数组 中
strings[1] = sb.toString();
} catch (IOException e) {
e.printStackTrace();
}
return strings;
}
记录日常出现的问题。既加深了印象,又有利于复习回顾!