Reputation: 3535
I need to be able to read a pem certificate that would be given to me by a client. For the purposes of testing, I created the key that I expect with:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days -1 -nodes
I then implemented a reader with:
public PublicKey getPublicKey()
throws Exception {
InputStream is = new ClassPathResource("cert.pem").getInputStream();
byte[] keyBytes = ByteStreams.toByteArray(is);
Base64.Decoder decoder = Base64.getDecoder();
String bytesAsString = new String(keyBytes, StandardCharsets.UTF_8);
System.out.println(bytesAsString);
X509EncodedKeySpec spec =
new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
The sysout presents the key, which appears to be well-formattd and about the right length. However on the last line I get the exception:
java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException: invalid key format
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:205)
at java.security.KeyFactory.generatePublic(KeyFactory.java:334)
at a.c.a.vaultorchestrator.service.VerifySignatureServiceTest.getPublicKey(VerifySignatureServiceTest.java:77)
at a.c.a.vaultorchestrator.service.VerifySignatureServiceTest.testVerifySignature(VerifySignatureServiceTest.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:211)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:67)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: java.security.InvalidKeyException: invalid key format
at sun.security.x509.X509Key.decode(X509Key.java:387)
at sun.security.x509.X509Key.decode(X509Key.java:403)
at sun.security.rsa.RSAPublicKeyImpl.<init>(RSAPublicKeyImpl.java:84)
at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:298)
at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:201)
... 29 more
Does anyone know why this is an invalid key?
Upvotes: 0
Views: 481
Reputation: 3535
Found the solution. The problem was that they keys needed to be converted to der format in order to be read by java. The following commands fixed the issue:
openssl rsa -in src/test/resources/key.pem -pubout -outform DER -out src/test/resources/cert.der
openssl pkcs8 -topk8 -inform PEM -outform DER -in key.pem -nocrypt -out key.der
With these two conversions done, and the obvious need to change the referenced public key in the code above to "cert.der", all went well.
Upvotes: 1