I need the ruby equivalent of the following:
openssl x509 -sha1 -fingerprint -noout -in cert.pem
The code that I wrote is:
data = File.read("cert.pem")
data["-----BEGIN CERTIFICATE-----\n"]=""
data["-----END CERTIFICATE-----\n"]=""
OpenSSL::Digest::SHA1.new(Base64.encode64(data))
This code does not generate the same fingerprint as the openssl cli command does.
Any idea what I may be doing wrong?
As gtrig mentions, the OpenSSL command line builds the fingerprint by hashing the DER encoding of the certificate, not the Base64 PEM representation. You can parse this using pure OpenSSL:
file_data = File.read("cert.pem")
cert = OpenSSL::X509::Certificate.new(file_data)
puts OpenSSL::Digest::SHA1.new(cert.to_der).to_s
Shameless plug: r509 can also do this like so:
cert = R509::Cert.load_from_file("cert.pem")
puts cert.fingerprint('sha1')
If you need it to be in colon separated form you can just take the hash and do something like "fingerprint".scan(/../).map{ |s| s.upcase }.join(":")
Try Base64.decode64.
OpenSSL::Digest::SHA1.new(Base64.decode64(data))
Certificates in PEM format are Base 64 encoded versions of a binary DER format, so they need to be DEcoded before the SHA1 hash is taken.
Alternatively, you could convert the PEM file to DER format with OpenSSL like this:
openssl x509 -in cert.pem -out cert.der -outform der
Then your Ruby code would look like this:
data2 = File.read("cert.der")
print OpenSSL::Digest::SHA1.new(data2)
Either way works.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With