RSA秘密鍵をJSONフォーマットで使用する
RSA秘密鍵をJSONフォーマットで使用する
概要
アプリケーション側でRSA署名をするにあたって、RSA秘密鍵をJSON形式で扱う機会がありました。やり方をまとめておきたいと思います。
RSA鍵の生成
RSA鍵の生成については、以下の記事に記載しましたので、ご覧ください。
RSA秘密鍵の構成要素
RSA秘密鍵の構成要素は、openssl
のコマンドでテキスト形式で出力できます。
下記コマンドを実行すると、秘密鍵の各パラメータ(モジュラス、公開指数、秘密指数、素因数など)が16進数で表示されます。
$ openssl rsa -in private_key.pem -text -noout
Private-Key: (2048 bit, 2 primes)
modulus:
00:ad:...略
publicExponent: 65537 (0x10001)
privateExponent:
25:1d:...略
prime1:
00:d7:...略
prime2:
00:cd:...略
exponent1:
04:06:...略
exponent2:
0a:37:...略
coefficient:
17:0c:...略
JSON形式にする方法
上で見た通り、秘密鍵の各パラメータは、16進数で表記されています。
これをJSON形式で保存する場合、Base64エンコードを施す必要があります。
16進数からBase64エンコードする
MacOSの場合
下記コマンドにより、指定した16進数の文字列をBase64エンコードできます。
$ echo "base64エンコードしたい16進数の文字列" | xxd -r -p | openssl base64
以下の流れで、Base64エンコードした結果が表示されます。
-
echo "base64エンコードしたい16進数の文字列"
: echo コマンドで16進数の文字列を標準出力します -
xxd -r -p
: 16進数の文字列がバイナリデータに変換されます。xxd
は、バイナリデータ↔︎16進数の変換に使われるLinuxコマンドです。-r
は逆変換のオプションであり、16進数のデータをバイナリに戻す機能を提供します。 -
openssl base64
: バイナリデータがBase64エンコードされます
Windowsの場合
Windowsの場合、Base64エンコードするPowerShellのScriptを用意します。
Param (
[string]$hex
)
$hex = $hex -replace "[:\s]", ""
# 16進数データをバイナリに変換
$bytes = for ($i = 0; $i -lt $hex.Length; $i += 2) {
[Convert]::ToByte($hex.Substring($i, 2), 16)
}
# バイト配列をBase64エンコード
$base64 = [Convert]::ToBase64String($bytes)
# Base64エンコード結果を表示
$base64
下記コマンドでBase64エンコードできます。
任意のディレクトリ\base64encode.ps1 -hex "16進数表記の値"
今回試していませんが、python
がインストールされていれば、python
でも簡単にBase64エンコードできそうです。
設定ファイルに保存する
前項でBase64エンコードした値をアプリケーション側に設定します。
例えば、appsettings.json
のような設定ファイルで、RSA秘密鍵のパラメータを次のように設定します。
{
"ClientSecret": {
"Modulus": "modulusの値をBase64エンコードした値",
"Exponent": "AQAB",
"D": "privateExponentの値をBase64エンコードした値",
"P": "prime1の値をBase64エンコードした値",
"Q": "prime2の値をBase64エンコードした値",
"DP": "exponent1の値をBase64エンコードした値",
"DQ": "exponent2の値をBase64エンコードした値",
"InverseQ": "coefficientの値をBase64エンコードした値"
}
}
このようにRSA秘密鍵の構成要素をJSON形式で定義することで、アプリケーション内で秘密鍵を利用できるようになります。例えば、APIクライアント認証の際、アプリケーションがこの鍵を使ってRSA署名を行うケースなどが考えられます。
もちろん、秘密鍵を設定ファイルに直接保存するのはNGです。実際にはAzure Key Vault
のようなKMS(Key Management Service)を使い、適切な場所に保管するのが大事です。
最後に
以上です。
秘密鍵をアプリケーション側で扱うケースは初めてだったので、やったことを整理しました。
RSAや暗号化などについては、「暗号技術入門」を読んでみたいなーと思ってます(積読)
Discussion