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-----