PEMのBASE64文字列からPrivateKeyを生成する方法

PEMをテキストファイルとして読み込んでjava.security.PrivateKeyを作る必要があったんだけど、読み取れるものと読み取れないものがあってちょっと困っていた。
読み取れないものは「not a sequence at ・・」みたいなエラーになってる。

で、良く見るとヘッダが異なる事に気がついた。
要するに PKCS#8 は読み込めるけど PKCS#1 はすんなり読んでくれないんですね。

ちなみに 見分け方は
-----BEGIN PUBLIC KEY-----
で始まってたら PKCS#8

-----BEGIN RSA PUBLIC KEY-----
で始まってたら PKCS#1

で、具体的なコードは下記のようになる。

PKCS8の時は簡単、PKCS8EncodedKeySpecにそのままバイト配列を食わせればOK。

String code "BASE64の文字列";
byte[] bytes = Base64.getDecoder.decode(code);

KeySpec spec = new PKCS8EncodedKeySpec(bytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(spec);

PKCS1の時はDerInputStreamを使ってパラメータを分解して、その情報からPrivateKeyを作成する。

String code "BASE64の文字列";
byte[] bytes = Base64.getDecoder.decode(code);

DerInputStream derReader = new DerInputStream(bytes);
DerValue[] seq = derReader.getSequence(0);

BigInteger modulus = seq(1).getBigInteger;
BigInteger publicExp = seq(2).getBigInteger;
BigInteger privateExp = seq(3).getBigInteger;
BigInteger prime1 = seq(4).getBigInteger;
BigInteger prime2 = seq(5).getBigInteger;
BigInteger exp1 = seq(6).getBigInteger;
BigInteger exp2 = seq(7).getBigInteger;
BigInteger crtCoef = seq(8).getBigInteger;

KeySpec spec = new RSAPrivateCrtKeySpec(
     modulus, publicExp, privateExp, prime1, prime2, exp1, exp2, crtCoef);
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(spec);

あ、ちなみにですが、“BASE64の文字列"はヘッダとフッタの間に記述されている文字列です。

-----BEGIN RSA PUBLIC KEY-----
      (ここの文字列)
-----END RSA PUBLIC KEY-----