尝试从文件加载 RSA public 密钥时发生 InvalidKeySpecException- Java

InvalidKeySpecException when trying to Load RSA public key from file- Java

我正在创建 public 和 RSA 私钥,并使用以下代码将它们保存到单独的文件中。文件创建成功,没有任何错误:

public static void main(String[] args) throws Exception {
    String path = "D:\OneDrive\Desktop\Keys\";

    KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
    kpg.initialize(2048);
    KeyPair kp = kpg.genKeyPair();

    ObjectOutputStream objOut = new ObjectOutputStream(new FileOutputStream(path + args[0] + ".pub"));
    System.out.println(kp.getPublic().getFormat());
    objOut.writeObject(kp.getPublic());
    objOut.close();

    objOut = new ObjectOutputStream(new FileOutputStream(path + args[0] + ".prv"));
    System.out.println(kp.getPrivate().getFormat());
    objOut.writeObject(kp.getPrivate());
    objOut.close();
}    

创建文件后,我想从文件中读取 public 密钥并使用该密钥加密一些字符串。要从文件中获取密钥,我使用以下代码:

private static PublicKey GetRecipientPublicKey(String filename)
        throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {

    Path path = Paths.get(basePath + filename + ".pub");
    byte[] arrByte = Files.readAllBytes(path);

    X509EncodedKeySpec publicSpec = new X509EncodedKeySpec(arrByte);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey publicKey = keyFactory.generatePublic(publicSpec);
    return publicKey;
}    

一旦代码 PublicKey publicKey = keyFactory.generatePublic(publicSpec); 在上面的代码中执行一个异常是抛出如下:

Exception in thread "main" java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: IOException: DerInputStream.getLength(): lengthTag=109, too big.
    at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:241)
    at java.base/java.security.KeyFactory.generatePublic(KeyFactory.java:351)
    at Client.GetRecipientPublicKey(Client.java:89)
    at Client.EncryptMessage(Client.java:66)
    at Client.main(Client.java:57)
    Caused by: java.security.InvalidKeyException: IOException: 
    DerInputStream.getLength(): lengthTag=109, too big.
    at java.base/sun.security.x509.X509Key.decode(X509Key.java:397)
    at java.base/sun.security.x509.X509Key.decode(X509Key.java:402)
    at java.base/sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:151)
    at java.base/sun.security.rsa.RSAPublicKeyImpl.newKey(RSAPublicKeyImpl.java:78)
    at java.base/sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:327)
    at java.base/sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:237)
    ... 4 more

现在您正在序列化 Key 对象,而不是编码形式。如果您在 Java SE 文档中阅读了 Key interface 的文档;您会发现以下内容:

An Encoded Form

This is an external encoded form for the key used when a standard representation of the key is needed outside the Java Virtual Machine, as when transmitting the key to some other party. The key is encoded according to a standard format (such as X.509 SubjectPublicKeyInfo or PKCS#8), and is returned using the getEncoded method.