前提
状況が激しくニッチ
状況
検証に利用する公開情報と、jwtデータの前半2つ(header, payload)はあるが肝心の署名データのサンプルがもらえてなくて開発時の検証テストが出来ない
ならせめて
公開情報のインタフェースを踏襲してstub化し、実際の製品のjwt検証コードの内容を変えずに検証処理を通したい
algはRS256
コード
実際の検証コードはtokenとx5nに相当するcerを容易に入れ替えられるしておき、
自前で署名つきjwtをこさえて、それを自前で検証できる状態にする。
※検証にはX509証明書チェーンを利用、e, nを利用する場合はここが参考になるかと思います
def tukuru
dn = OpenSSL::X509::Name.new
dn.add_entry 'C', 'JP'
dn.add_entry 'ST', 'Kanagawa'
dn.add_entry 'DC', 'Kawasaki'
dn.add_entry 'O', 'foo'
dn.add_entry 'CN', 'bar'
rsa = OpenSSL::PKey::RSA.generate 2048
cer = OpenSSL::X509::Certificate.new
cer.not_before = Time.now
cer.not_after = Time.now + 20 * 365 * 24 * 60 * 60 # 有効期限は適当に(これは20年)
cer.public_key = rsa.public_key
cer.serial = 1
cer.issuer = dn
cer.subject = dn
ex = OpenSSL::X509::Extension.new 'basicConstraints', OpenSSL::ASN1.Sequence([OpenSSL::ASN1::Boolean(true)])
cer.add_extension ex
cer.sign rsa, OpenSSL::Digest::SHA1.new
File.open('yourpath/test_private.pem', 'wb') { |f| f.write(rsa.export) }
File.open('yourpath/test_cer.pem', 'wb') { |f| f.write(cer.to_pem) }
nil
end
def siraberu
cer = File.read('yourpath/test_cer.pem') # 実検証時はここを外部から取得する
rsa = OpenSSL::PKey::RSA.new(File.read('yourpath/test_private.pem'))
header = {
'foo': 'bar'
}
claims = {
'daichi': 'oppore'
}
token = JWT.encode(claims, rsa, 'RS256', header) # 実検証時はここが他人が作ったtokenとなる
public_key = OpenSSL::X509::Certificate.new(cer).public_key
JWT.decode(token, public_key, true, algorithm: 'RS256')
end
サンプルなので1メソッドの中でグチャグチャやってますがノリは伝わるかと
こんな状態に陥る人はそうはいないと思いますが、同一の状態で困ったらとりあえずこれでゴリ押せます
わざわざファイルにしてるのは、実際にはfixture的にこの鍵ファイルを保持してそいつをテストコードの中で読み出して使うケースのが多そうだからです
テストコードでしか利用しない、機密にする理由がゼロの鍵やしね