Generating X509 Certificates in Ruby

The following code snippet generates an X509 Certificate using ruby. The certificate can be used for winrm setup. The certificate generation params can be modified to have a certificate that suits your purpose.

The output of the code below is:
key.pem – RSA private key
cert.pem – Certificate in PEM format
cert.pfx – Certificate in PFX format
cert_encoded.pfx – Certificate in PFX encoded format
cert_encoded.der – Certificate in encoded DER format
cert.cer – Certificate in CER format

require ‘openssl’

rsa_key = OpenSSL::PKey::RSA.new(2048)
rsa_key.public_key

#private key
puts rsa_key

#public key
puts rsa_key.public_key

#we can encrypt the private key. Create a Cipher object and using it, convert the key pair to PEM format
# following not needed for the winrm certgen
cipher = OpenSSL::Cipher::Cipher.new(‘des3′)
private_key = rsa_key.to_pem(cipher,’password’)
public_key = rsa_key.public_key.to_pem

# encrypted private key
puts private_key

#Create a self-signed X509 certificate from the rsa_key (unencrypted)
# The following certificate that is generated can be used on windows for use in winrm
certname=”test”
hostname=”hostname”

cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = Random.rand(65534) + 1 # 2 digit byte range random number for better security aspect
cert.subject = OpenSSL::X509::Name.parse “/CN=#{hostname}”
cert.issuer = cert.subject
cert.public_key = rsa_key.public_key
cert.not_before = Time.now
cert.not_after = cert.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = cert
ef.issuer_certificate = cert
cert.add_extension(ef.create_extension(“subjectKeyIdentifier”,”hash”,false))
cert.add_extension(ef.create_extension(“authorityKeyIdentifier”,”keyid:always”,false))
cert.add_extension(ef.create_extension(“extendedKeyUsage”, “1.3.6.1.5.5.7.3.1”, false))
cert.sign(rsa_key, OpenSSL::Digest::SHA1.new)

File.write(“#{certname}_cert.pem”, cert.to_pem.to_s )

pfx = OpenSSL::PKCS12.create(‘winrmcertgen’, ‘winrmcertgen’, rsa_key, cert)
File.open(“#{certname}_cert.pfx”, “wb”) { |f| f.print pfx.to_der }

puts OpenSSL::Digest::SHA1.new(cert.to_der)

require ‘base64’
File.open( “#{certname}_cert_encoded.pfx”, “wb”) { |f| f.print Base64.encode64(cert.to_pem)}

File.open(“#{certname}_cert_encoded.der”, “wb”) { |f| f.print Base64.strict_encode64(pfx.to_der) }

File.open(“#{certname}_cert.cer”, “wb”) { |f| f.print Base64.strict_encode64(cert.to_der) }

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s