2

I am working on a RoR website that requires an e-payment module. The e-payment implementation requires that the xml data is encoded using a public ssl key provided by them.

What I tried to do in Ruby:

public_key = OpenSSL::PKey::RSA.new(File.read(public_key_file))

If I just try to open the file separately it works fine. But the RSA.new() method returns the following error:

OpenSSL::PKey::RSAError: Neither PUB key nor PRIV key:: nested asn1 error
    from (irb):5:in `initialize'
    from (irb):5:in `new'
    from (irb):5

From what I've seen in the online documentation a .pem file is used but my public key is something like public.cer. Could that be the problem ? The key itself seems to be OK for in the PHP example provided by the e-payment company the same public.cer file works fine.

What am I doing wrong?

Thanks,

Brayn
  • 1,766
  • 10
  • 27
  • 33

4 Answers4

9

The .cer file is most likely a X.509 certificate encoded in DER. Unfortunately, Ruby doesn't expose the OpenSSL interface to read certificate in DER. So you need to convert the DER to PEM first. This is fairly easy in Ruby,

b64 = Base64.encode64(File::read(cert_file))
pem = "-----BEGIN CERTIFICATE-----\n#{b64}-----END CERTIFICATE-----\n"
cert = OpenSSL::X509::Certificate.new(pem)
public_key = cert.public_key
Mukesh Singh Rathaur
  • 12,577
  • 2
  • 23
  • 24
ZZ Coder
  • 74,484
  • 29
  • 137
  • 169
  • I have tried your solution and it works fine until I do: "cert = OpenSSL::X509::Certificate.new(pem)" at which point it gives me the same error message. Also I have noticed some "\n" characters in the certificate code, could this be the problem? Thanks – Brayn Dec 17 '09 at 09:07
  • I have tried the new version of the code with no luck. Thanks anyway. – Brayn Dec 18 '09 at 10:29
  • If you post a hexdump of the file, I may be able to find out the problem. – ZZ Coder Dec 18 '09 at 11:15
  • getting error with Base64.b64encode(File::read(cert_file), 64), I think It's Base64.encode64(File::read(cert_file)) – CodecPM Nov 23 '16 at 12:10
  • use this `Base64.encode64(File::read(cert_file))`. "b64encode" method missing for Base64 module. – Mukesh Singh Rathaur Mar 02 '17 at 06:17
2

Just an update - the current openssl gem for ruby 1.9.3 supports reading certificates from file in DER and PEM format.

cert = OpenSSL::X509::Certificate.new('certificate.pem')
cert = OpenSSL::X509::Certificate.new('certificate.cer')

See the documentation at http://www.ruby-doc.org/stdlib-1.9.3/libdoc/openssl/rdoc/OpenSSL/X509/Certificate.html.

FuePi
  • 1,958
  • 22
  • 18
0

Try replacing File.read with File.binread.

Depending on your platform (Windows is most susceptible) File.read may not return what you expect. Using File.binread will make sure you get the actual binary data of the binary certificate you are reading and want to work with.

Some background on the difference: https://stackoverflow.com/a/30081354/252627

janpio
  • 10,645
  • 16
  • 64
  • 107
0

You can find information about the different encodings for certificates here: http://www.gtopia.org/blog/2010/02/der-vs-crt-vs-cer-vs-pem-certificates/

Try to convert your certificate from der format to pem.

openssl x509 –in input.crt –inform DER –out output.pem
Peder
  • 2,739
  • 3
  • 31
  • 33