I am creating public and private RSA keys and saving them to separate files using the code below. The file are successfully created without any error:
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();
}
After creating the files I want to read the public key from the file and encrypt some string using that key. To get the key from the file I am using the code below:
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;
}
As soon as the code PublicKey publicKey = keyFactory.generatePublic(publicSpec); in above code is executed an exception is thrown as follow:
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
Right now you are serializing the Key
object, not the encoded form. If you read the documentation for the Key interface in the Java SE documentation; you will find the following:
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.