2
votes

I've generated a self signed certificate using Adobe X, and exported a pfx file (for my private key) along with a .cer file (for the certificate).

I then try to collect the certificate, along with the key, but for some reason, OpenSSL is giving the error

OpenSSL::X509::CertificateError: not enough data

Here is my code

require 'openssl'

CERTFILE = "test.cer"
RSAKEYFILE = "test.pfx"

# Open certificate files

cert = OpenSSL::X509::Certificate.new(File.read CERTFILE)
key = OpenSSL::PKey::RSA.new(File.read RSAKEYFILE )

My certificate was generated using Adobe X reader, and is a self-signed certificate. It is working fine to sign pdf documents...

What might i do to make this work?

2

2 Answers

4
votes

Apparently OpenSSL has some problems reading directly from .cer files, and for the key, we should use only the private_key, and the pfx has both the privatekey and the cert.

So, i installed openSsl locally, and first converted my .cer certificate to .pem with the following command :

C:\OpenSSL-Win32\bin>openssl x509 -inform der -in "c:\mydir\test.cer" -out "C:\mydir\certificate.pem"

and then extracted my privatekey from the pfx file (based on this site) :

C:\OpenSSL-Win32\bin>openssl pkcs12 -in "c:\mydir\test.pfx" -nocerts -out "c:\mydir\test_pk.pem"

just make sure you have your pfx pwd and select a passphrase when you extract the privatekey.

Here is the final code :

require 'openssl'

CERTFILE = "certificate.pem"
RSAKEYFILE = "test_pk.pem"
passphrase = "your chosen passphrase for the private key"
key4pem=File.read RSAKEYFILE

# Open certificate files

cert = OpenSSL::X509::Certificate.new(File.read CERTFILE)
key = OpenSSL::PKey::RSA.new key4pem, passphrase

And voilá :-), we have successfully mapped into memory both our certificate and privatekey, and can put it to uses like the answer here

2
votes

While trying to create an OpenSSL::X509::Certificate object from '.cer', I found this error:

OpenSSL::X509::CertificateError (not enough data)

I checked that file was actually a DER-encoded certificate which is in binary format. In that case, we should read the file contents by File.binread.

To check if the file is PEM or DER encoded? We can use the following code:

require "open3"
require "openssl"

def pem_cert?(file)
  details, status = Open3.capture2e("file", file)
  return false unless status.success?
  details.rpartition(":").last.strip == "PEM certificate"
end

contents = if pem_cert?(cer_file_path)
    File.read(cer_file_path)
  else
    File.binread(cer_file_path)
  end

OpenSSL::X509::Certificate.new(contents)

This is a pure ruby way, without any shell interaction.