JWT 検証デバッグの 昨日 の続き。
署名が正しいか自力で検証する。
openssl 準備
macOS の openssl
コマンドを確認する。
$ openssl version LibreSSL 2.6.5
OpenSSL が欲しいので brew
でいれる。
$ brew instal openssl ... 適当にパスを通して $ openssl version OpenSSL 1.1.1g 21 Apr 2020
検証する JWT
テスト用なので見られても困らないので、 token
もここで公開します。
これを利用して検証を行う。
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJmNGJWZXlRZWFTMVNieDkxWXVLaSJ9.eyJpc3MiOiJodHRwczovL29tdXJvbi51cy5hdXRoMC5jb20vIiwic3ViIjoiaWV5ZGt1M0Q3QVRDbm5BN2ZHaFJ5anZobjQ0NVNmQ1NAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vb211cm9uLnVzLmF1dGgwLmNvbS9hcGkvdjIvIiwiaWF0IjoxNTkyNTYzMTU3LCJleHAiOjE1OTI2NDk1NTcsImF6cCI6ImlleWRrdTNEN0FUQ25uQTdmR2hSeWp2aG40NDVTZkNTIiwic2NvcGUiOiJyZWFkOmNsaWVudF9ncmFudHMgY3JlYXRlOmNsaWVudF9ncmFudHMgZGVsZXRlOmNsaWVudF9ncmFudHMgdXBkYXRlOmNsaWVudF9ncmFudHMgcmVhZDp1c2VycyB1cGRhdGU6dXNlcnMgZGVsZXRlOnVzZXJzIGNyZWF0ZTp1c2VycyByZWFkOnVzZXJzX2FwcF9tZXRhZGF0YSB1cGRhdGU6dXNlcnNfYXBwX21ldGFkYXRhIGRlbGV0ZTp1c2Vyc19hcHBfbWV0YWRhdGEgY3JlYXRlOnVzZXJzX2FwcF9tZXRhZGF0YSByZWFkOnVzZXJfY3VzdG9tX2Jsb2NrcyBjcmVhdGU6dXNlcl9jdXN0b21fYmxvY2tzIGRlbGV0ZTp1c2VyX2N1c3RvbV9ibG9ja3MgY3JlYXRlOnVzZXJfdGlja2V0cyByZWFkOmNsaWVudHMgdXBkYXRlOmNsaWVudHMgZGVsZXRlOmNsaWVudHMgY3JlYXRlOmNsaWVudHMgcmVhZDpjbGllbnRfa2V5cyB1cGRhdGU6Y2xpZW50X2tleXMgZGVsZXRlOmNsaWVudF9rZXlzIGNyZWF0ZTpjbGllbnRfa2V5cyByZWFkOmNvbm5lY3Rpb25zIHVwZGF0ZTpjb25uZWN0aW9ucyBkZWxldGU6Y29ubmVjdGlvbnMgY3JlYXRlOmNvbm5lY3Rpb25zIHJlYWQ6cmVzb3VyY2Vfc2VydmVycyB1cGRhdGU6cmVzb3VyY2Vfc2VydmVycyBkZWxldGU6cmVzb3VyY2Vfc2VydmVycyBjcmVhdGU6cmVzb3VyY2Vfc2VydmVycyByZWFkOmRldmljZV9jcmVkZW50aWFscyB1cGRhdGU6ZGV2aWNlX2NyZWRlbnRpYWxzIGRlbGV0ZTpkZXZpY2VfY3JlZGVudGlhbHMgY3JlYXRlOmRldmljZV9jcmVkZW50aWFscyByZWFkOnJ1bGVzIHVwZGF0ZTpydWxlcyBkZWxldGU6cnVsZXMgY3JlYXRlOnJ1bGVzIHJlYWQ6cnVsZXNfY29uZmlncyB1cGRhdGU6cnVsZXNfY29uZmlncyBkZWxldGU6cnVsZXNfY29uZmlncyByZWFkOmhvb2tzIHVwZGF0ZTpob29rcyBkZWxldGU6aG9va3MgY3JlYXRlOmhvb2tzIHJlYWQ6YWN0aW9ucyB1cGRhdGU6YWN0aW9ucyBkZWxldGU6YWN0aW9ucyBjcmVhdGU6YWN0aW9ucyByZWFkOmVtYWlsX3Byb3ZpZGVyIHVwZGF0ZTplbWFpbF9wcm92aWRlciBkZWxldGU6ZW1haWxfcHJvdmlkZXIgY3JlYXRlOmVtYWlsX3Byb3ZpZGVyIGJsYWNrbGlzdDp0b2tlbnMgcmVhZDpzdGF0cyByZWFkOnRlbmFudF9zZXR0aW5ncyB1cGRhdGU6dGVuYW50X3NldHRpbmdzIHJlYWQ6bG9ncyByZWFkOnNoaWVsZHMgY3JlYXRlOnNoaWVsZHMgdXBkYXRlOnNoaWVsZHMgZGVsZXRlOnNoaWVsZHMgcmVhZDphbm9tYWx5X2Jsb2NrcyBkZWxldGU6YW5vbWFseV9ibG9ja3MgdXBkYXRlOnRyaWdnZXJzIHJlYWQ6dHJpZ2dlcnMgcmVhZDpncmFudHMgZGVsZXRlOmdyYW50cyByZWFkOmd1YXJkaWFuX2ZhY3RvcnMgdXBkYXRlOmd1YXJkaWFuX2ZhY3RvcnMgcmVhZDpndWFyZGlhbl9lbnJvbGxtZW50cyBkZWxldGU6Z3VhcmRpYW5fZW5yb2xsbWVudHMgY3JlYXRlOmd1YXJkaWFuX2Vucm9sbG1lbnRfdGlja2V0cyByZWFkOnVzZXJfaWRwX3Rva2VucyBjcmVhdGU6cGFzc3dvcmRzX2NoZWNraW5nX2pvYiBkZWxldGU6cGFzc3dvcmRzX2NoZWNraW5nX2pvYiByZWFkOmN1c3RvbV9kb21haW5zIGRlbGV0ZTpjdXN0b21fZG9tYWlucyBjcmVhdGU6Y3VzdG9tX2RvbWFpbnMgdXBkYXRlOmN1c3RvbV9kb21haW5zIHJlYWQ6ZW1haWxfdGVtcGxhdGVzIGNyZWF0ZTplbWFpbF90ZW1wbGF0ZXMgdXBkYXRlOmVtYWlsX3RlbXBsYXRlcyByZWFkOm1mYV9wb2xpY2llcyB1cGRhdGU6bWZhX3BvbGljaWVzIHJlYWQ6cm9sZXMgY3JlYXRlOnJvbGVzIGRlbGV0ZTpyb2xlcyB1cGRhdGU6cm9sZXMgcmVhZDpwcm9tcHRzIHVwZGF0ZTpwcm9tcHRzIHJlYWQ6YnJhbmRpbmcgdXBkYXRlOmJyYW5kaW5nIGRlbGV0ZTpicmFuZGluZyByZWFkOmxvZ19zdHJlYW1zIGNyZWF0ZTpsb2dfc3RyZWFtcyBkZWxldGU6bG9nX3N0cmVhbXMgdXBkYXRlOmxvZ19zdHJlYW1zIGNyZWF0ZTpzaWduaW5nX2tleXMgcmVhZDpzaWduaW5nX2tleXMgdXBkYXRlOnNpZ25pbmdfa2V5cyByZWFkOmxpbWl0cyB1cGRhdGU6bGltaXRzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0.TJyTQQpBq0j6X-Smq8qcNkChbBxAFJT_xFNn8Bc2Uv-UP2KZsGRq801bLKdTgNUz2Wp8FT15i4LHCDwv1qhxpgMN9LdlL3uqNmzFgFcWXHnsToARf9mV3Hyi_QYZSzugrzql4jEZyITOhaxelThcko4FVZ4rL6-Tc4ZoZlkgY_6PgPlRrC5DXZR74-iVoruydPlo3lCnJmQkx4jcNCtqYXXpQsKCjCxoDD_Jzb_x16RMUczxrBqNuo6VSVjsiyPmkisdpsCzgwH8xZIK8dGJ_lDtV26GSOui6Gg9dN5smVGHBuDuaP_WYvAEh8qCkxFE5Z6WOrvvnyvGgNzRquuajA
公開鍵保存
昨日取得した公開鍵を pem
ファイルに保存しておく。
( pub
のほうが名前としては正しいかもだけど)
$ echo "-----BEGIN CERTIFICATE----- MIIDATCCAemgAwIBAgIJbOX8RffC+u+LMA0GCSqGSIb3DQEBCwUAMB4xHDAaBgNVBAMTE29tdXJvbi51cy5hdXRoMC5jb20wHhcNMjAwNjE5MDgxMjAwWhcNMzQwMjI2MDgxMjAwWjAeMRwwGgYDVQQDExNvbXVyb24udXMuYXV0aDAuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA5HgBZMeT0iwu24jS9KsDQX85GLwU9kdbLYnuq/IT8LFENrUH7WxUhRaIaS3FvA4T/OCVNdVcJ+nPH++Gq2AlW4rkv+BBp963IICj9dwYbwZFFKeSlUMp2/QYdg2HeBZLJpqM8z6MhC8tejvWfAZ7Pblu3hICP5wyByDzjF9BiDDfrxdugfUGP0RtRe9EK1+51ZhByO8Hss4mIgoyrDOaw6R0vxJYxJCivOpvhhaKuSvEr+rA4tvOEkd3yeC5JqMyzLb/wouF9Md+0foxpzOrgoYnlIR02zcgnzlMHyRbV5Soaj1nokeXhMmIxU5d8BGNgSn+KX3lIexEHj5XchUUUwIDAQABo0IwQDAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSSScOdNOvjZ/oiJTaKoRk21MXjVzAOBgNVHQ8BAf8EBAMCAoQwDQYJKoZIhvcNAQELBQADggEBAIKHXiXfdzB7IS2N2oeI2519aoFukgx5gzfeG7lecjFDGo4CVxt8ez1/oF9ZZeIopZ150zEtkWOuU4C0IvkKNqT5MyKBfW38ED23SPXuuuPdqXcmlsL7AaKpNYuFTAE7escc1yJ2ddVGWRh+F+jeyAii+cP+5LxDyz39p3wBTeB9Am0RiXnNG+nXkPtT/y/MJ7H7jqjoK5zUHcveLRvxfp2K2RDpZtzDV2u0L+SzsPPgi27VCaCKchZpih2I9SDvhXVMKXLWm5mir8triXBjfYIYcSOz/UqzgpxJp6H9wzyaIfrxBMnMWsMF82movhwINV9bSXl475FpLVvEcUvMwp0= -----END CERTIFICATE-----" > pem
JWT の署名を取り出す
JWT の3つめのセクションが、署名になる。
base64 デコードが必要なので、4byte パディングの調整を =
で行い、情報を確認。
$ echo "TJyTQQpBq0j6X-Smq8qcNkChbBxAFJT_xFNn8Bc2Uv-UP2KZsGRq801bLKdTgNUz2Wp8FT15i4LHCDwv1qhxpgMN9LdlL3uqNmzFgFcWXHnsToARf9mV3Hyi_QYZSzugrzql4jEZyITOhaxelThcko4FVZ4rL6-Tc4ZoZlkgY_6PgPlRrC5DXZR74-iVoruydPlo3lCnJmQkx4jcNCtqYXXpQsKCjCxoDD_Jzb_x16RMUczxrBqNuo6VSVjsiyPmkisdpsCzgwH8xZIK8dGJ_lDtV26GSOui6Gg9dN5smVGHBuDuaP_WYvAEh8qCkxFE5Z6WOrvvnyvGgNzRquuajA==" | base64 -D | hexdump -C 00000000 4c 9c 93 41 0a 41 ab 48 fa 5f e4 a6 ab ca 9c 36 |L..A.A.H._.....6| 00000010 40 a1 6c 1c 40 14 94 ff c4 53 67 f0 17 36 52 ff |@.l.@....Sg..6R.| 00000020 94 3f 62 99 b0 64 6a f3 4d 5b 2c a7 53 80 d5 33 |.?b..dj.M[,.S..3| 00000030 d9 6a 7c 15 3d 79 8b 82 c7 08 3c 2f d6 a8 71 a6 |.j|.=y....</..q.| 00000040 03 0d f4 b7 65 2f 7b aa 36 6c c5 80 57 16 5c 79 |....e/{.6l..W.\y| 00000050 ec 4e 80 11 7f d9 95 dc 7c a2 fd 06 19 4b 3b a0 |.N......|....K;.| 00000060 af 3a a5 e2 31 19 c8 84 ce 85 ac 5e 95 38 5c 92 |.:..1......^.8\.| 00000070 8e 05 55 9e 2b 2f af 93 73 86 68 66 59 20 63 fe |..U.+/..s.hfY c.| 00000080 8f 80 f9 51 ac 2e 43 5d 94 7b e3 e8 95 a2 bb b2 |...Q..C].{......| 00000090 74 f9 68 de 50 a7 26 64 24 c7 88 dc 34 2b 6a 61 |t.h.P.&d$...4+ja| 000000a0 75 e9 42 c2 82 8c 2c 68 0c 3f c9 cd bf f1 d7 a4 |u.B...,h.?......| 000000b0 4c 51 cc f1 ac 1a 8d ba 8e 95 49 58 ec 8b 23 e6 |LQ........IX..#.| 000000c0 92 2b 1d a6 c0 b3 83 01 fc c5 92 0a f1 d1 89 fe |.+..............| 000000d0 50 ed 57 6e 86 48 eb a2 e8 68 3d 74 de 6c 99 51 |P.Wn.H...h=t.l.Q| 000000e0 87 06 e0 ee 68 ff d6 62 f0 04 87 ca 82 93 11 44 |....h..b.......D| 000000f0 e5 9e 96 3a bb ef 9f 2b c6 80 dc d1 aa eb 9a 8c |...:...+........| 00000100
この内容を jwt.sign
に保存する。
$ echo "TJyTQQpBq0j6X-Smq8qcNkChbBxAFJT_xFNn8Bc2Uv-UP2KZsGRq801bLKdTgNUz2Wp8FT15i4LHCDwv1qhxpgMN9LdlL3uqNmzFgFcWXHnsToARf9mV3Hyi_QYZSzugrzql4jEZyITOhaxelThcko4FVZ4rL6-Tc4ZoZlkgY_6PgPlRrC5DXZR74-iVoruydPlo3lCnJmQkx4jcNCtqYXXpQsKCjCxoDD_Jzb_x16RMUczxrBqNuo6VSVjsiyPmkisdpsCzgwH8xZIK8dGJ_lDtV26GSOui6Gg9dN5smVGHBuDuaP_WYvAEh8qCkxFE5Z6WOrvvnyvGgNzRquuajA==" | base64 -D > jwt.sign
OpenSSL でハッシュ値確認
$ openssl rsautl -verify -asn1parse -in jwt.sign -certin -inkey pem 0:d=0 hl=2 l= 49 cons: SEQUENCE 2:d=1 hl=2 l= 13 cons: SEQUENCE 4:d=2 hl=2 l= 9 prim: OBJECT :sha256 15:d=2 hl=2 l= 0 prim: NULL 17:d=1 hl=2 l= 32 prim: OCTET STRING 0000 - 30 55 55 70 f7 d2 4e c4-35 91 de 57 70 b7 4a c5 0UUp..N.5..Wp.J. 0010 - ab 26 62 d5 58 23 d1 59-3c 3f 31 95 be 1b 35 9e .&b.X#.Y<?1...5.
最後の2行のハッシュ値が、SHA256の出力結果であることが確認できる。
SHA256 ハッシュの検証
JWT の 「ヘッダー + .
+ ペイロード」と同じ値か、 shasum -a 256
コマンドを利用して検証を行う。
echo -n "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6ImJmNGJWZXlRZWFTMVNieDkxWXVLaSJ9.eyJpc3MiOiJodHRwczovL29tdXJvbi51cy5hdXRoMC5jb20vIiwic3ViIjoiaWV5ZGt1M0Q3QVRDbm5BN2ZHaFJ5anZobjQ0NVNmQ1NAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vb211cm9uLnVzLmF1dGgwLmNvbS9hcGkvdjIvIiwiaWF0IjoxNTkyNTYzMTU3LCJleHAiOjE1OTI2NDk1NTcsImF6cCI6ImlleWRrdTNEN0FUQ25uQTdmR2hSeWp2aG40NDVTZkNTIiwic2NvcGUiOiJyZWFkOmNsaWVudF9ncmFudHMgY3JlYXRlOmNsaWVudF9ncmFudHMgZGVsZXRlOmNsaWVudF9ncmFudHMgdXBkYXRlOmNsaWVudF9ncmFudHMgcmVhZDp1c2VycyB1cGRhdGU6dXNlcnMgZGVsZXRlOnVzZXJzIGNyZWF0ZTp1c2VycyByZWFkOnVzZXJzX2FwcF9tZXRhZGF0YSB1cGRhdGU6dXNlcnNfYXBwX21ldGFkYXRhIGRlbGV0ZTp1c2Vyc19hcHBfbWV0YWRhdGEgY3JlYXRlOnVzZXJzX2FwcF9tZXRhZGF0YSByZWFkOnVzZXJfY3VzdG9tX2Jsb2NrcyBjcmVhdGU6dXNlcl9jdXN0b21fYmxvY2tzIGRlbGV0ZTp1c2VyX2N1c3RvbV9ibG9ja3MgY3JlYXRlOnVzZXJfdGlja2V0cyByZWFkOmNsaWVudHMgdXBkYXRlOmNsaWVudHMgZGVsZXRlOmNsaWVudHMgY3JlYXRlOmNsaWVudHMgcmVhZDpjbGllbnRfa2V5cyB1cGRhdGU6Y2xpZW50X2tleXMgZGVsZXRlOmNsaWVudF9rZXlzIGNyZWF0ZTpjbGllbnRfa2V5cyByZWFkOmNvbm5lY3Rpb25zIHVwZGF0ZTpjb25uZWN0aW9ucyBkZWxldGU6Y29ubmVjdGlvbnMgY3JlYXRlOmNvbm5lY3Rpb25zIHJlYWQ6cmVzb3VyY2Vfc2VydmVycyB1cGRhdGU6cmVzb3VyY2Vfc2VydmVycyBkZWxldGU6cmVzb3VyY2Vfc2VydmVycyBjcmVhdGU6cmVzb3VyY2Vfc2VydmVycyByZWFkOmRldmljZV9jcmVkZW50aWFscyB1cGRhdGU6ZGV2aWNlX2NyZWRlbnRpYWxzIGRlbGV0ZTpkZXZpY2VfY3JlZGVudGlhbHMgY3JlYXRlOmRldmljZV9jcmVkZW50aWFscyByZWFkOnJ1bGVzIHVwZGF0ZTpydWxlcyBkZWxldGU6cnVsZXMgY3JlYXRlOnJ1bGVzIHJlYWQ6cnVsZXNfY29uZmlncyB1cGRhdGU6cnVsZXNfY29uZmlncyBkZWxldGU6cnVsZXNfY29uZmlncyByZWFkOmhvb2tzIHVwZGF0ZTpob29rcyBkZWxldGU6aG9va3MgY3JlYXRlOmhvb2tzIHJlYWQ6YWN0aW9ucyB1cGRhdGU6YWN0aW9ucyBkZWxldGU6YWN0aW9ucyBjcmVhdGU6YWN0aW9ucyByZWFkOmVtYWlsX3Byb3ZpZGVyIHVwZGF0ZTplbWFpbF9wcm92aWRlciBkZWxldGU6ZW1haWxfcHJvdmlkZXIgY3JlYXRlOmVtYWlsX3Byb3ZpZGVyIGJsYWNrbGlzdDp0b2tlbnMgcmVhZDpzdGF0cyByZWFkOnRlbmFudF9zZXR0aW5ncyB1cGRhdGU6dGVuYW50X3NldHRpbmdzIHJlYWQ6bG9ncyByZWFkOnNoaWVsZHMgY3JlYXRlOnNoaWVsZHMgdXBkYXRlOnNoaWVsZHMgZGVsZXRlOnNoaWVsZHMgcmVhZDphbm9tYWx5X2Jsb2NrcyBkZWxldGU6YW5vbWFseV9ibG9ja3MgdXBkYXRlOnRyaWdnZXJzIHJlYWQ6dHJpZ2dlcnMgcmVhZDpncmFudHMgZGVsZXRlOmdyYW50cyByZWFkOmd1YXJkaWFuX2ZhY3RvcnMgdXBkYXRlOmd1YXJkaWFuX2ZhY3RvcnMgcmVhZDpndWFyZGlhbl9lbnJvbGxtZW50cyBkZWxldGU6Z3VhcmRpYW5fZW5yb2xsbWVudHMgY3JlYXRlOmd1YXJkaWFuX2Vucm9sbG1lbnRfdGlja2V0cyByZWFkOnVzZXJfaWRwX3Rva2VucyBjcmVhdGU6cGFzc3dvcmRzX2NoZWNraW5nX2pvYiBkZWxldGU6cGFzc3dvcmRzX2NoZWNraW5nX2pvYiByZWFkOmN1c3RvbV9kb21haW5zIGRlbGV0ZTpjdXN0b21fZG9tYWlucyBjcmVhdGU6Y3VzdG9tX2RvbWFpbnMgdXBkYXRlOmN1c3RvbV9kb21haW5zIHJlYWQ6ZW1haWxfdGVtcGxhdGVzIGNyZWF0ZTplbWFpbF90ZW1wbGF0ZXMgdXBkYXRlOmVtYWlsX3RlbXBsYXRlcyByZWFkOm1mYV9wb2xpY2llcyB1cGRhdGU6bWZhX3BvbGljaWVzIHJlYWQ6cm9sZXMgY3JlYXRlOnJvbGVzIGRlbGV0ZTpyb2xlcyB1cGRhdGU6cm9sZXMgcmVhZDpwcm9tcHRzIHVwZGF0ZTpwcm9tcHRzIHJlYWQ6YnJhbmRpbmcgdXBkYXRlOmJyYW5kaW5nIGRlbGV0ZTpicmFuZGluZyByZWFkOmxvZ19zdHJlYW1zIGNyZWF0ZTpsb2dfc3RyZWFtcyBkZWxldGU6bG9nX3N0cmVhbXMgdXBkYXRlOmxvZ19zdHJlYW1zIGNyZWF0ZTpzaWduaW5nX2tleXMgcmVhZDpzaWduaW5nX2tleXMgdXBkYXRlOnNpZ25pbmdfa2V5cyByZWFkOmxpbWl0cyB1cGRhdGU6bGltaXRzIiwiZ3R5IjoiY2xpZW50LWNyZWRlbnRpYWxzIn0" | shasum -a 256 30555570f7d24ec43591de5770b74ac5ab2662d55823d1593c3f3195be1b359e -
30555570f7d24ec43591de5770b74ac5ab2662d55823d1593c3f3195be1b359e
の値が、 openssl rsautl
と同じ値であることが確認できる。
これを用いて、JWT が改ざんされていないか検証している。
以上
やっと、やっっと自力で JWT の署名が検証できた!