ここ数年前から2015までのモダンフロントエンドを総まとめしてみた
mmmuser
デロイト トーマツ ウェブサービス株式会社(DWS)公式ブログ
JavaScriptを使って、ブラウザ上で、p12ファイルからpemの書式で証明書と秘密鍵を取得してみます。
以下、forgeというライブラリを使って実装してゆきます。ブラウザで読み込むには、以下のようにminファイルを読み込む必要があります。
const forge = require('node-forge/dist/forge.min.js');
p12ファイルはブラウザで添付される想定ですので、まずは、以下のようにして、ファイルを解読可能にします。
// p12Bufferは、添付されたファイルをBufferに変換したもの
const p12String = p12Buffer.toString('base64');
// base64からデコード
const p12Der = forge.util.decode64(p12String);
// ASN.1オブジェクトを取得
const p12Asn1 = forge.asn1.fromDer(p12Der);
// p12ファイルを読み込み
const p12 = forge.pkcs12.pkcs12FromAsn1(p12Asn1);
注意点としては、p12ファイルにパスワードを設定する場合は、forge.pkcs12.pkcs12FromAsn1(p12Asn1, 'password')
のようにする必要があることです。Google API Consoleで取得した場合はデフォルトでnotasecret
になっていたりするので、要件にあわせて実装を行ってください。
証明書は以下のように取得できます。Bagは、p12ファイルにおける、情報を入れておく箱のようなものです。
// Bagタイプから証明書を取得
// https://tools.ietf.org/html/rfc7292#section-4.2.3
const cert = p12.getBags({ bagType: forge.pki.oids.certBag })[forge.pki.oids.certBag][0].cert;
// pemの書式で取得
const pemCert = forge.pki.certificateToPem(cert);
秘密鍵も基本的には同様ですが、間に変換の処理が入ります。
// Bagタイプから秘密鍵を取得。秘密鍵なのでPKCS#8で取り出せる
// https://tools.ietf.org/html/rfc7292#section-4.2.2
const privateKey = p12.getBags({ bagType: forge.pki.oids.pkcs8ShroudedKeyBag })[forge.pki.oids.pkcs8ShroudedKeyBag][0].key;
// ASN.1のRSA秘密鍵に変換
const rsaPrivateKey = forge.pki.privateKeyToAsn1(privateKey);
// PKCS#8のPrivateKeyInfoでラップする
// https://tools.ietf.org/html/rfc5208#section-5
const privateKeyInfo = forge.pki.wrapRsaPrivateKey(rsaPrivateKey);
// pemの書式で取得
const pemPrivate = forge.pki.privateKeyInfoToPem(privateKeyInfo);
秘密鍵はp12.getBags({friendlyName: "privatekey"})
のようにfriendlyName
をつかって取得することもできますが、基本的に任意で設定できてしまうので、Bagタイプで取るのがよさそうです。
/*
出力:
-----BEGIN CERTIFICATE-----
base64エンコード
-----END CERTIFICATE-----
*/
console.log(pemCert.replace(/
/g, '
'))
/*
出力:
-----BEGIN PRIVATE KEY-----
base64エンコード
-----END PRIVATE KEY-----
*/
console.log(pemPrivate.replace(/
/g, '
'))
無事pem書式で情報を取得できました。