title: RSA keys transformation for Java - clarification needed?
body: <p>I read a bit about the known issue of transforming keys from PEM to DER so Java can read them, and I ran up <a href="http://codeartisan.blogspot.com/2009/05/public-key-cryptography-in-java.html" rel="nofollow">this article</a>. When followed through, this works OK - generated RSA key pair with <code>openssl</code>, keys are loaded fine, and what is encrypted with public key is successfully decoded with the private key.</p>
  
  <p>Now, here's the unclear part.<br>
  Not so long ago, I generated PKI using Easy-RSA utility, while setting up OpenVPN server. Here, a self-signed cert was created. Output files, among others are:  </p>
  
  <blockquote>
    <p>server.csr ------ // certificate request<br>
    server.key ------// private key<br>
    server.crt -------// self-signed certificate/public-key/whatever this is..?</p>
  </blockquote>
  
  <p>Just for the reference, <a href="http://openvpn.net/index.php/open-source/documentation/miscellaneous/77-rsa-key-management.html" rel="nofollow">easy-RSA is documented</a> (on the bottom of the page are the scripts explained, and we can see <code>openssl</code> commands actually used in the process).   </p>
  
  <p>So, I tried the above logic on these files, using <code>server.key</code> as my private key file, and  <code>server.crt</code> as my public key file, <strong>both previously transformed</strong> to Java-readable DER format:  </p>
  
  <blockquote>
    <p>openssl pkcs8 -topk8 -inform PEM -outform DER -in server.key -out server_private_key.der -nocrypt
    openssl x509 -inform PEM -outform DER -text -in server.crt -out server.der</p>
  </blockquote>
  
  <p>Private key, not so strangely, works OK, i.e. it is successfully loaded in Java.<br>
  Public key (again, probably not so strangely) won't load, but I don't know the reason, since I'm not really familiar with all these things. My guess is that this has something to do with certificate being signed, and I wonder how to deal with this in those cases. I get the following exception:  </p>
  
  <pre><code>java.security.spec.InvalidKeySpecException: java.security.InvalidKeyException:IOException: ObjectIdentifier() -- data isn't an object ID (tag = -96)
    at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:188)
    at java.security.KeyFactory.generatePublic(KeyFactory.java:304)
    at aes.utils.KeyReaderUtil.getPublicKeyFromFile(KeyReaderUtil.java:57)
    at aes.utils.Main.main(Main.java:69)
  Caused by: java.security.InvalidKeyException: IOException: ObjectIdentifier() -- data
  isn't an object ID (tag = -96)
    at sun.security.x509.X509Key.decode(X509Key.java:380)
    at sun.security.x509.X509Key.decode(X509Key.java:386)
    at sun.security.rsa.RSAPublicKeyImpl.&lt;init&gt;(RSAPublicKeyImpl.java:66)
    at sun.security.rsa.RSAKeyFactory.generatePublic(RSAKeyFactory.java:281)
    at sun.security.rsa.RSAKeyFactory.engineGeneratePublic(RSAKeyFactory.java:184)
    ... 3 more
  </code></pre>
  
  <p>Furthermore, when I "export" the public key from the existing <code>server.key</code> private key file, like this (as in the above article):  </p>
  
  <blockquote>
    <p>openssl rsa -in server.key -pubout -outform DER -out server_public_key.der</p>
  </blockquote>
  
  <p>it all works fine again.  </p>
  
  <p>So, my question is: what is the right way, and why <code>server.crt</code> won't load as public key ?</p>