IOException : DerInputStream.getLength(): lengthTag=105, too big.

223 阅读2分钟

image.png 持续创作,加速成长!这是我参与「掘金日新计划 · 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;
}

记录日常出现的问题。既加深了印象,又有利于复习回顾!