とある会社のAPIに接続するため、その会社が発行した証明書・秘密鍵を用いて アクセスをする必要がありました。
いつもと違って独自のCERT/Private keyでアクセスする必要があり、 RubyのNet::HTTPでハマってしまったのでここにメモを残します。
いつものHTTPSのやり方
url = "http://example.com/foo/bar"
uri = URI.parse(url)
req = Net::HTTP::Post.new(uri.path)
params = {your_data: 1}
req.set_form_data(params)
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
res = https.start { |h| h.request(req) }
puts res.code
puts res.body
こんな風にしてあげれば、良い感じにできます。
ポイントは、https.use_ssl = true
でhttpsを設定してあげる事
ぐらいでしょうか。
独自の証明書や秘密鍵でSSL接続する
色々とネットを調べてみたのですが、情報が散乱してて意外とハマってしまいまいした。
パスフレーズ付きの秘密鍵をdecrypt(復号)する
パスフレーズで復号するのを忘れて、随分時間を無駄にしてしまいました…orz
cert_file_path = "path/to/your_cert.pem"
passphrase = "YourPassphrase"
key = OpenSSL::PKey::RSA.new(File.read(cert_file_path), passphrase)
このように、OpenSSL::PKey::RSA.new
にCertファイルとパスフレーズを渡してあげると復号してくれます。
key
とcert
を設定してあげる
https.key = OpenSSL::PKey::RSA.new(File.read(cert_file_path), passphrase)
https.cert = OpenSSL::X509::Certificate.new(File.read(cert_file_path))
https.ca_file = "/path/to/your_cert.pem"
のようにファイルをそのまま渡してしまう例が多かったのですが、
今回はパスフレーズで秘密鍵を復号化しないといけなかったので、上記のように直接
https.key
とhttps.cert
を自分で設定するようにしました。
(* 今回のCERTファイルはPEMファイルで、中にCertificateとPrivate keyの両方が含まれるタイプでした。)
最終的に以下のようにする事でうまく行きました。
url = "http://example.com/foo/bar"
uri = URI.parse(url)
req = Net::HTTP::Post.new(uri.path)
params = {your_data: 1}
req.set_form_data(params)
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
cert_file_path = "path/to/your_cert.pem"
passphrase = "YourPassphrase" # Change to your passphrase
https.key = OpenSSL::PKey::RSA.new(File.read(cert_file_path), passphrase)
https.cert = OpenSSL::X509::Certificate.new(File.read(cert_file_path))
https.verify_mode = OpenSSL::SSL::VERIFY_PEER
https.verify_depth = 5
res = https.start { |h| h.request(req) }
puts res.code
puts res.body
よく使うNet::HTTP
ですが、思いがけずハマってしまいました。
これが誰かの役に立てば幸いです。