X509証明書のv3拡張にはSubject Key Identifier (SKI)というものがある。
このSKIはそのままでX509証明書に含まれる公開鍵の識別子である。
$ openssl x509 -text -noout -in server.crt
Certificate:
Data:
Version: 3 (0x2)
Serial Number: 13130459247485585328 (0xb638c31e101f07b0)
Signature Algorithm: ecdsa-with-SHA256
Issuer: CN=root ca
Validity
Not Before: Aug 4 14:53:26 2020 GMT
Not After : Aug 4 14:53:26 2021 GMT
Subject: CN=server
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (256 bit)
pub:
04:18:76:24:20:7e:90:d5:8e:a9:76:3d:1b:0f:56:
01:f1:4e:6f:7f:43:71:2c:3f:86:15:45:08:03:2e:
d4:2d:d1:12:c9:f1:9e:4f:a6:03:dc:6b:50:ab:a7:
c0:4a:62:cc:0f:64:7b:00:fe:9a:d7:84:89:5b:35:
e4:e8:c2:50:32
ASN1 OID: prime256v1
NIST CURVE: P-256
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost
X509v3 Subject Key Identifier:
5B:77:97:D1:B9:03:E2:C4:31:F6:84:3F:E6:70:51:BB:86:DD:DD:87
Signature Algorithm: ecdsa-with-SHA256
30:46:02:21:00:e0:39:08:21:72:e8:8c:0c:65:5f:e4:34:ed:
04:bb:69:80:75:e8:d8:05:23:33:e3:6c:27:5d:49:50:a4:45:
72:02:21:00:af:e8:84:50:95:fc:36:6f:01:13:03:90:f2:f0:
21:20:cc:0d:42:70:98:c4:af:6a:78:5d:ef:7f:cf:d8:d3:a8
このSKIはopensslコマンドを使用する場合、証明書署名時に以下のような設定のextfileをオプションで与えると書き込まれる
subjectKeyIdentifier = hash
そしてこのhash、ただ公開鍵のハッシュを求めるのかと思ったら違った。。。
OpenSSLの説明(x509v3_config)を見ると2つの設定があるらしい。
- hashが設定されていたらRFC5258に従って計算したハッシュ値が入る
- 他の設定(違う文字列?)なら16進の文字列が入る(非推奨)
とのこと
そしてRFC5258には公開鍵からSKIを求める方法は一般的に2つあると書いてある
- 1つは公開鍵のBIT STRING(excluding the tag, length and number of unused bits)のSHA1ハッシュ
- もう1つは4bitのタイプフィールドとそれに続く公開鍵のBIT STRINGのSHA1ハッシュの最下位60bit
らしいが、
あくまで一般的な方法の例なので、ユニークな識別子を生成できるなら他の方法でも良い。
ここでopensslのhashという設定は前者になる模様
そんでもってここで言うBIT STRINGとは公開鍵ファイルからタグや長さ等のメタ情報を除いたもの。
これはopensslのasn1parseで求めることができる。
- まずパースして構造をチェック
ここでは23がBIT STRINGのオフセットである(オフセットは鍵のアルゴリズムによって変わる)$ openssl asn1parse -in pub.key 0:d=0 hl=2 l= 89 cons: SEQUENCE 2:d=1 hl=2 l= 19 cons: SEQUENCE 4:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey 13:d=2 hl=2 l= 8 prim: OBJECT :prime256v1 23:d=1 hl=2 l= 66 prim: BIT STRING
- BIT STRINGのオフセットを設定してパース
$ openssl asn1parse -in pub.key -strparse 23 -noout -out pub.bin
これでBIT STRINGが求められたのであとはハッシュ(SHA1)の計算をするだけ
$ openssl sha1 pub.bin
SHA1(pub.bin)= 5b7797d1b903e2c431f6843fe67051bb86dddd87
↓ 証明書のSKI(再掲)
X509v3 Subject Key Identifier:
5B:77:97:D1:B9:03:E2:C4:31:F6:84:3F:E6:70:51:BB:86:DD:DD:87
ちょっと表現が違いますが、見比べてみると全く同じSHA1の160bitのハッシュ値ですねヽ(・∀・)ノ ワチョーイ♪
コメントする