class OpenSSL::X509::Certificate

Implementierung eines X.509-Zertifikats gemäß RFC 5280. Bietet Zugriff auf die Attribute eines Zertifikats und ermöglicht das Lesen von Zertifikaten aus einem String, unterstützt aber auch die Erstellung neuer Zertifikate von Grund auf.

Ein Zertifikat aus einer Datei lesen

Certificate kann DER-kodierte Zertifikate und Zertifikate im PEM-Format von OpenSSL verarbeiten.

raw = File.binread "cert.cer" # DER- or PEM-encoded
certificate = OpenSSL::X509::Certificate.new raw

Ein Zertifikat in eine Datei speichern

Ein Zertifikat kann im DER-Format kodiert werden

cert = ...
File.open("cert.cer", "wb") { |f| f.print cert.to_der }

oder im PEM-Format

cert = ...
File.open("cert.pem", "wb") { |f| f.print cert.to_pem }

X.509-Zertifikate sind mit einem privaten/öffentlichen Schlüsselpaar verbunden, typischerweise einem RSA-, DSA- oder ECC-Schlüssel (siehe auch OpenSSL::PKey::RSA, OpenSSL::PKey::DSA und OpenSSL::PKey::EC). Der öffentliche Schlüssel selbst ist im Zertifikat gespeichert und kann in Form eines OpenSSL::PKey abgerufen werden. Zertifikate werden typischerweise verwendet, um einem Schlüsselpaar eine Art Identität zuzuordnen, zum Beispiel verwenden Webserver, die Seiten über HTTPs ausliefern, Zertifikate, um sich dem Benutzer zu authentifizieren.

Das Public Key Infrastructure (PKI)-Modell basiert auf vertrauenswürdigen Zertifizierungsstellen („Root CAs“), die diese Zertifikate ausstellen, so dass Endbenutzer ihr Vertrauen nur auf eine ausgewählte Anzahl von Stellen stützen müssen, die wiederum untergeordnete Stellen beglaubigen, die ihre Zertifikate an Endbenutzer ausstellen.

Das Modul OpenSSL::X509 bietet die Werkzeuge zur Einrichtung einer unabhängigen PKI, ähnlich wie Szenarien, in denen das Kommandozeilentool 'openssl' zum Ausstellen von Zertifikaten in einer privaten PKI verwendet wird.

Erstellung eines Root-CA-Zertifikats und eines Endbenutzer-Zertifikats

Zuerst müssen wir ein „selbstsigniertes“ Root-Zertifikat erstellen. Dazu müssen wir zuerst einen Schlüssel generieren. Bitte beachten Sie, dass die Wahl von „1“ als Seriennummer für echte Zertifikate als Sicherheitslücke gilt. Sichere Wahlmöglichkeiten sind Ganzzahlen im zweistelligen Bytebereich und idealerweise keine sequentiellen, sondern sichere Zufallszahlen. Schritte hier zur Kürze des Beispiels ausgelassen.

root_key = OpenSSL::PKey::RSA.new 2048 # the CA's public/private key
root_ca = OpenSSL::X509::Certificate.new
root_ca.version = 2 # cf. RFC 5280 - to make it a "v3" certificate
root_ca.serial = 1
root_ca.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby CA"
root_ca.issuer = root_ca.subject # root CA's are "self-signed"
root_ca.public_key = root_key.public_key
root_ca.not_before = Time.now
root_ca.not_after = root_ca.not_before + 2 * 365 * 24 * 60 * 60 # 2 years validity
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = root_ca
ef.issuer_certificate = root_ca
root_ca.add_extension(ef.create_extension("basicConstraints","CA:TRUE",true))
root_ca.add_extension(ef.create_extension("keyUsage","keyCertSign, cRLSign", true))
root_ca.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
root_ca.add_extension(ef.create_extension("authorityKeyIdentifier","keyid:always",false))
root_ca.sign(root_key, OpenSSL::Digest.new('SHA256'))

Der nächste Schritt ist die Erstellung des Endbenutzer-Zertifikats unter Verwendung des Root-CA-Zertifikats.

key = OpenSSL::PKey::RSA.new 2048
cert = OpenSSL::X509::Certificate.new
cert.version = 2
cert.serial = 2
cert.subject = OpenSSL::X509::Name.parse "/DC=org/DC=ruby-lang/CN=Ruby certificate"
cert.issuer = root_ca.subject # root CA is the issuer
cert.public_key = key.public_key
cert.not_before = Time.now
cert.not_after = cert.not_before + 1 * 365 * 24 * 60 * 60 # 1 years validity
ef = OpenSSL::X509::ExtensionFactory.new
ef.subject_certificate = cert
ef.issuer_certificate = root_ca
cert.add_extension(ef.create_extension("keyUsage","digitalSignature", true))
cert.add_extension(ef.create_extension("subjectKeyIdentifier","hash",false))
cert.sign(root_key, OpenSSL::Digest.new('SHA256'))