开发者社区 问答 正文

加载RSA公钥错误DerInputStream.getLength():lengthTag = 10

我需要加密JSON数据,以便使用公共RSA密钥在http正文中发送它,我加载了公共RSA密钥文件(.der),并且工作正常。

客户端向我发送了一个公共RSA密钥文件(.bin)。因此,当我运行程序时,出现此错误

Caused by: java.security.InvalidKeyException: IOException: DerInputStream.getLength(): lengthTag=109, too big.
    at sun.security.x509.X509Key.decode(X509Key.java:380) ~[na:1.6.0_45]
    at sun.security.x509.X509Key.decode(X509Key.java:386) ~[na:1.6.0_45]
    at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:66) ~[na:1.6.0_45

我的PublicKeyReader类:

public class PublicKeyReader {

  public static PublicKey getpublicKey(String filename)
    throws Exception {

      File file = new File(filename);
      FileInputStream fis = new FileInputStream(filename);
      DataInputStream dis = new DataInputStream(fis);
      byte[] keyBytes = new byte[(int) file.length()];
      dis.readFully(keyBytes);
      dis.close();


    X509EncodedKeySpec spec =
      new X509EncodedKeySpec(keyBytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");

    return kf.generatePublic(spec);
  }
}

在我的主类中,加密部分是:

// Encrypt Data with AES
        byte[] keyData = random.generateSeed(16);
        SecretKey skeySpec = new SecretKeySpec(keyData, "AES");
        Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
        byte[] ivParams = new byte[aes.getBlockSize()];
        IvParameterSpec iv = new IvParameterSpec(ivParams);
        aes.init(Cipher.ENCRYPT_MODE, skeySpec, iv);

        // Lecture du certificat (cle publique RSA)
        PublicKey clePublique = PublicKeyReader.getpublicKey("./src/main/resources/publique.bin");
        //String clePublique1 = Base64.encodeBase64String(clePublique.getEncoded()).replaceAll(
        //      "(\\r|\\n)", "");
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.WRAP_MODE, clePublique);
        byte[] wrappedKey = cipher.wrap(skeySpec);

        // encodedToken : Mot de passe symétrique crypté avec le certificat
        // public (RSA) mis à la disposition de la banque par BAM
        String encodedToken = Base64.encodeBase64String(wrappedKey).replaceAll(
                "(\\r|\\n)", "");
        ;

展开
收起
垚tutu 2019-12-04 16:25:24 3896 分享 版权
阿里云 AI 助理回答

这个错误信息表明您尝试加载的公钥文件格式不正确,导致DerInputStream.getLength()方法报错,说长度标签太大。这通常意味着您可能使用了错误的文件类型或文件内容不是预期的X.509编码格式的RSA公钥。

根据您的描述,问题出在处理.bin文件作为RSA公钥上。.der文件通常用于存储X.509编码的密钥或证书,而.bin文件可能没有遵循相同的格式规范,或者它可能是以不同的方式编码的(比如PKCS#1格式而非X.509/SPKI)。

为了解决这个问题,您可以尝试以下步骤:

  1. 确认文件格式:首先确保客户端发送给您的.bin文件确实是一个X.509编码的RSA公钥。如果不是,请获取正确的格式或转换文件格式。

  2. 检查和转换文件格式:如果.bin文件是PKCS#1格式的RSA公钥,您需要将其转换为X.509/SPKI格式才能被Java的KeyFactory.getInstance("RSA")正确解析。可以使用OpenSSL工具进行转换:

    openssl rsa -in publique.bin -pubout -outform DER -out publique.der
    

    这将把PKCS#1格式的公钥转换成DER编码的X.509公钥,并保存为publique.der

  3. 更新代码以适应不同格式:修改您的PublicKeyReader类以支持多种格式,或者明确指定只接受特定格式的公钥文件。

  4. 异常处理和日志记录:增强异常处理逻辑,提供更详细的错误信息,帮助快速定位问题。

  5. 使用Base64解码:如果.bin文件实际上是Base64编码的公钥数据,您需要先解码再处理:

    byte[] keyBytes = Base64.getDecoder().decode(new String(keyData));
    

请按照上述建议操作,特别是确认和转换文件格式的部分,这很可能是解决您当前问题的关键。

有帮助
无帮助
AI 助理回答生成答案可能存在不准确,仅供参考
0 条回答
写回答
取消 提交回答