こんにちは!SmartHRで文書配付機能の開発をしているakhtです。
最近イカ釣りにハマっています。先日イカを釣り上げたとき、はじめてイカスミ攻撃を喰らってしまいました。イカスミで黒く染まった服は記念として大事にとっておく……ということはなく、洗っても落ちなかったので普通に処分しました。
イカ釣りをしていないときは文書配付という機能の開発をしています。
文書配付では、従業員に対して雇用契約書などのPDFデータを送ることができます。従業員は送られてきたPDFを確認し、内容に合意すれば電子署名することができます。この電子署名やその他の仕組みを組み合わせることで、推定効(文書が真正に成立したものと推定できる)を受けるための要件を実現しています。
PDFに電子署名をするということは、電子証明書が必要になりますよね。そして電子証明書を発行してもらうためにはCSR(証明書署名要求)が必要です。 この記事では、Google CloudのCloud Key Management Service(以下、Cloud KMS)で管理している秘密鍵を用いて、CSRをお手軽、簡単に作成する方法を紹介します。
なお、実際の運用では暗号鍵はCloud HSMで管理するケースもあると思いますが、Cloud HSMはCloud KMSをフロントエンドとして使用するため、この記事では「Cloud KMSで管理する鍵」のような表現をしています。
まず公式ドキュメントにはどう書かれている?
Cloud KMSで管理している秘密鍵でCSRを作成する方法は公式ドキュメントで紹介されています。 cloud.google.com
このドキュメントではOpenSSLでCloud KMSの暗号鍵を利用できるように構成する手順が紹介されています。
とてもわかりやすく説明されており、特段むずかしい点はなさそうに思います。 ですが、あえていうならDebian環境の用意やパッケージのインストール、ライブラリの設定などがほんのちょっとだけめんどくさい感じがしますね……。
Goで書かれたツールを紹介します
そんなときは、Goで書かれたjuliendsv/google-cloud-kms-csr を使うとお手軽にCSRを生成できます。
github.com
まず、リポジトリをcloneしてビルドします。
$ go build -o csr
あとは、署名に利用する鍵のリソースやディスティングイッシュネームを指定して実行するだけです。
なお、実行にはcloudkms.cryptoKeyVersions.viewPublicKeyとcloudkms.cryptoKeyVersions.useToSignのIAM権限が必要です。
$ ./csr -key <key-resource-id> -out my.csr --common-name MyOrg
必要に応じて署名アルゴリズムを変更できます。
実装を読んでみる
このスクリプトで使われている x509.CreateCertificateRequest()関数 では、3つ目の引数(priv)で crypto.Signerインターフェース を実装したインスタンスを指定するようになっています。
func CreateCertificateRequest(rand io.Reader, template *CertificateRequest, priv any) (csr []byte, err error)
Cloud KMS APIでは公開鍵の取得と署名ができるので、Public()とSign()どちらのメソッドもCloud KMS上の秘密鍵を利用するように実装することができます。
よって、秘密鍵を直接参照できるケースと同じように x509.CreateCertificateRequest()関数 を呼び出すことができるようでした。便利!
Rubyで同じものが書けるか?
ためしにRubyで同等のスクリプトを書いてみようと思ったんですが、今回のように秘密鍵を直接参照できないケースではOpenSSL::X509::Requestを作るのは難しそうでした。
そもそもOpenSSLを扱うためのライブラリなので、前述した公式ドキュメントのようにPKCS #11のモジュールがなければ実行できなさそうですね。
一応、OpenSSL::ASN1モジュールを用いてCSRのデータを構成し、それに対してCloud KMS APIで署名をすれば有効なCSRを作成できるかもしれません。が、ちょっと大変そうではありますね……。これなら普通に公式ドキュメント通りにやるのがよさそうです。
ということで、juliendsv/google-cloud-kms-csrが便利だよという紹介でした。
We are hiring!!
文書配付機能では、会社と従業員間の文書のやり取りにおけるさまざまなユースケースに対応できるように絶賛機能開発中です。加えてPDFに電子署名するモジュールのリプレースも進めています。
契約書のペーパーレス化やPDF/電子署名に興味のある方、ぜひカジュアル面談でお話ししましょう!