InvalidKeySpecException When Trying To Load RSA Public Key From File- Java
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
Answer
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.
Related Questions
- → How to update data attribute on Ajax complete
- → October CMS - Radio Button Ajax Click Twice in a Row Causes Content to disappear
- → Octobercms Component Unique id (Twig & Javascript)
- → Passing a JS var from AJAX response to Twig
- → Laravel {!! Form::open() !!} doesn't work within AngularJS
- → DropzoneJS & Laravel - Output form validation errors
- → Import statement and Babel
- → Uncaught TypeError: Cannot read property '__SECRET_DOM_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
- → React-router: Passing props to children
- → ListView.DataSource looping data for React Native
- → Can't test submit handler in React component
- → React + Flux - How to avoid global variable
- → Webpack, React & Babel, not rendering DOM