module OpenSSL
OpenSSL bietet SSL, TLS und allgemeine Kryptographie. Es umschließt die OpenSSL-Bibliothek.
Beispiele
Alle Beispiele setzen voraus, dass Sie OpenSSL mit
require 'openssl'
geladen haben. Diese Beispiele bauen aufeinander auf. Zum Beispiel wird der im nächsten Schritt erstellte Schlüssel in allen folgenden Beispielen verwendet.
Schlüssel
Schlüssel erstellen
Dieses Beispiel erstellt ein RSA-Schlüsselpaar mit 2048 Bit und schreibt es in das aktuelle Verzeichnis.
key = OpenSSL::PKey::RSA.new 2048 File.write 'private_key.pem', key.private_to_pem File.write 'public_key.pem', key.public_to_pem
Schlüssel exportieren
Auf der Festplatte ohne Verschlüsselung gespeicherte Schlüssel sind nicht sicher, da jeder, der den Schlüssel in die Hände bekommt, ihn verwenden kann, es sei denn, er ist verschlüsselt. Um einen Schlüssel sicher zu exportieren, können Sie ihn mit einem Passwort exportieren.
cipher = OpenSSL::Cipher.new 'aes-256-cbc' password = 'my secure password goes here' key_secure = key.private_to_pem cipher, password File.write 'private.secure.pem', key_secure
OpenSSL::Cipher.ciphers gibt eine Liste der verfügbaren Verschlüsselungsalgorithmen zurück.
Schlüssel laden
Ein Schlüssel kann auch aus einer Datei geladen werden.
key2 = OpenSSL::PKey.read File.read 'private_key.pem' key2.public? # => true key2.private? # => true
oder
key3 = OpenSSL::PKey.read File.read 'public_key.pem' key3.public? # => true key3.private? # => false
Verschlüsselten Schlüssel laden
OpenSSL wird Sie beim Laden eines verschlüsselten Schlüssels nach Ihrem Passwort fragen. Wenn Sie das Passwort nicht eingeben können, können Sie es beim Laden des Schlüssels angeben.
key4_pem = File.read 'private.secure.pem' password = 'my secure password goes here' key4 = OpenSSL::PKey.read key4_pem, password
RSA-Verschlüsselung
RSA bietet Verschlüsselung und Entschlüsselung mit öffentlichen und privaten Schlüsseln. Sie können verschiedene Padding-Methoden verwenden, abhängig vom beabsichtigten Verwendungszweck der verschlüsselten Daten.
Verschlüsselung & Entschlüsselung
Asymmetrische Public/Private-Key-Verschlüsselung ist langsam und anfällig für Angriffe, wenn sie ohne Padding oder direkt zum Verschlüsseln größerer Datenmengen verwendet wird. Typische Anwendungsfälle für RSA-Verschlüsselung beinhalten das „Verpacken“ eines symmetrischen Schlüssels mit dem öffentlichen Schlüssel des Empfängers, der diesen symmetrischen Schlüssel dann wieder mit seinem privaten Schlüssel „entpacken“ würde. Das Folgende illustriert ein vereinfachtes Beispiel eines solchen Schlüsselaustauschschemas. Es sollte jedoch nicht in der Praxis verwendet werden; standardisierte Protokolle sollten immer bevorzugt werden.
wrapped_key = key.public_encrypt key
Ein mit dem öffentlichen Schlüssel verschlüsselter symmetrischer Schlüssel kann nur mit dem entsprechenden privaten Schlüssel des Empfängers entschlüsselt werden.
original_key = key.private_decrypt wrapped_key
Standardmäßig wird PKCS#1-Padding verwendet, aber es ist auch möglich, andere Padding-Formen zu verwenden. Weitere Details finden Sie unter PKey::RSA.
Signaturen
Die Verwendung von „private_encrypt“ zum Verschlüsseln von Daten mit dem privaten Schlüssel ist gleichbedeutend mit dem Anwenden einer digitalen Signatur auf die Daten. Eine verifizierende Partei kann die Signatur validieren, indem sie das Ergebnis der Entschlüsselung der Signatur mit „public_decrypt“ mit den Originaldaten vergleicht. OpenSSL::PKey verfügt jedoch bereits über die Methoden „sign“ und „verify“, die digitale Signaturen auf standardisierte Weise handhaben – „private_encrypt“ und „public_decrypt“ sollten in der Praxis nicht verwendet werden.
Um ein Dokument zu signieren, wird zuerst ein kryptografisch sicherer Hash des Dokuments berechnet, der dann mit dem privaten Schlüssel signiert wird.
signature = key.sign 'SHA256', document
Um die Signatur zu validieren, wird erneut ein Hash des Dokuments berechnet und die Signatur mit dem öffentlichen Schlüssel entschlüsselt. Das Ergebnis wird dann mit dem gerade berechneten Hash verglichen. Wenn sie gleich sind, war die Signatur gültig.
if key.verify 'SHA256', signature, document puts 'Valid' else puts 'Invalid' end
PBKDF2-Passwortbasierte Verschlüsselung
Wenn von der zugrunde liegenden OpenSSL-Version unterstützt, sollte die passwortbasierte Verschlüsselung die Funktionen von PKCS5 nutzen. Wenn dies nicht unterstützt wird oder wenn es von älteren Anwendungen benötigt wird, werden auch die älteren, weniger sicheren Methoden, die in RFC 2898 spezifiziert sind, unterstützt (siehe unten).
PKCS5 unterstützt PBKDF2, wie es in PKCS#5 v2.0 spezifiziert wurde. Es verwendet immer noch ein Passwort, ein Salt und zusätzlich eine Anzahl von Iterationen, die den Schlüsselableitungsprozess verlangsamen. Je langsamer dies ist, desto mehr Aufwand ist erforderlich, um den resultierenden Schlüssel per Brute-Force zu knacken.
Verschlüsselung
Die Strategie besteht darin, zuerst einen Cipher für die Verschlüsselung zu instanziieren und dann einen zufälligen IV sowie einen aus dem Passwort mittels PBKDF2 abgeleiteten Schlüssel zu generieren. PKCS #5 v2.0 empfiehlt mindestens 8 Bytes für das Salt. Die Anzahl der Iterationen hängt stark von der verwendeten Hardware ab.
cipher = OpenSSL::Cipher.new 'aes-256-cbc'
cipher.encrypt
iv = cipher.random_iv
pwd = 'some hopefully not to easily guessable password'
salt = OpenSSL::Random.random_bytes 16
iter = 20000
key_len = cipher.key_len
digest = OpenSSL::Digest.new('SHA256')
key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
cipher.key = key
Now encrypt the data:
encrypted = cipher.update document
encrypted << cipher.final
Entschlüsselung
Verwenden Sie die gleichen Schritte wie zuvor, um den symmetrischen AES-Schlüssel abzuleiten, und konfigurieren Sie diesmal den Cipher für die Entschlüsselung.
cipher = OpenSSL::Cipher.new 'aes-256-cbc'
cipher.decrypt
cipher.iv = iv # the one generated with #random_iv
pwd = 'some hopefully not to easily guessable password'
salt = ... # the one generated above
iter = 20000
key_len = cipher.key_len
digest = OpenSSL::Digest.new('SHA256')
key = OpenSSL::PKCS5.pbkdf2_hmac(pwd, salt, iter, key_len, digest)
cipher.key = key
Now decrypt the data:
decrypted = cipher.update encrypted
decrypted << cipher.final
X509-Zertifikate
Zertifikat erstellen
Dieses Beispiel erstellt ein selbstsigniertes Zertifikat mit einem RSA-Schlüssel und einer SHA1-Signatur.
key = OpenSSL::PKey::RSA.new 2048 name = OpenSSL::X509::Name.parse '/CN=nobody/DC=example' cert = OpenSSL::X509::Certificate.new cert.version = 2 cert.serial = 0 cert.not_before = Time.now cert.not_after = Time.now + 3600 cert.public_key = key.public_key cert.subject = name
Zertifikat-Erweiterungen
Sie können dem Zertifikat mit OpenSSL::SSL::ExtensionFactory Erweiterungen hinzufügen, um den Zweck des Zertifikats anzugeben.
extension_factory = OpenSSL::X509::ExtensionFactory.new nil, cert cert.add_extension \ extension_factory.create_extension('basicConstraints', 'CA:FALSE', true) cert.add_extension \ extension_factory.create_extension( 'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature') cert.add_extension \ extension_factory.create_extension('subjectKeyIdentifier', 'hash')
Die Liste der unterstützten Erweiterungen (und in einigen Fällen ihrer möglichen Werte) kann aus der Datei „objects.h“ im Quellcode von OpenSSL abgeleitet werden.
Zertifikat signieren
Um ein Zertifikat zu signieren, legen Sie den Aussteller fest und verwenden Sie OpenSSL::X509::Certificate#sign mit einem Digest-Algorithmus. Dies erstellt ein selbstsigniertes Zertifikat, da wir denselben Namen und Schlüssel zum Signieren des Zertifikats verwenden, der für die Erstellung des Zertifikats verwendet wurde.
cert.issuer = name cert.sign key, OpenSSL::Digest.new('SHA1') open 'certificate.pem', 'w' do |io| io.write cert.to_pem end
Zertifikat laden
Ähnlich wie ein Schlüssel kann auch ein Zertifikat aus einer Datei geladen werden.
cert2 = OpenSSL::X509::Certificate.new File.read 'certificate.pem'
Zertifikat verifizieren
Certificate#verify gibt true zurück, wenn ein Zertifikat mit dem gegebenen öffentlichen Schlüssel signiert wurde.
raise 'certificate can not be verified' unless cert2.verify key
Zertifizierungsstelle
Eine Zertifizierungsstelle (CA) ist eine vertrauenswürdige dritte Partei, die es Ihnen ermöglicht, den Besitz unbekannter Zertifikate zu überprüfen. Die CA stellt Schlüssel assinatura aus, die anzeigen, dass sie dem Benutzer dieses Schlüssels vertraut. Ein Benutzer, der auf den Schlüssel stößt, kann die Signatur mit dem öffentlichen Schlüssel der CA überprüfen.
CA-Schlüssel
CA-Schlüssel sind wertvoll, daher verschlüsseln und speichern wir sie auf der Festplatte und stellen sicher, dass sie für andere Benutzer nicht lesbar sind.
ca_key = OpenSSL::PKey::RSA.new 2048 password = 'my secure password goes here' cipher = 'aes-256-cbc' open 'ca_key.pem', 'w', 0400 do |io| io.write ca_key.private_to_pem(cipher, password) end
CA-Zertifikat
Ein CA-Zertifikat wird auf die gleiche Weise erstellt wie das obige Zertifikat, jedoch mit anderen Erweiterungen.
ca_name = OpenSSL::X509::Name.parse '/CN=ca/DC=example' ca_cert = OpenSSL::X509::Certificate.new ca_cert.serial = 0 ca_cert.version = 2 ca_cert.not_before = Time.now ca_cert.not_after = Time.now + 86400 ca_cert.public_key = ca_key.public_key ca_cert.subject = ca_name ca_cert.issuer = ca_name extension_factory = OpenSSL::X509::ExtensionFactory.new extension_factory.subject_certificate = ca_cert extension_factory.issuer_certificate = ca_cert ca_cert.add_extension \ extension_factory.create_extension('subjectKeyIdentifier', 'hash')
Diese Erweiterung gibt an, dass der Schlüssel der CA als CA verwendet werden kann.
ca_cert.add_extension \ extension_factory.create_extension('basicConstraints', 'CA:TRUE', true)
Diese Erweiterung gibt an, dass der Schlüssel der CA zur Verifizierung von Signaturen auf Zertifikaten und Zertifikatswiderrufen verwendet werden kann.
ca_cert.add_extension \ extension_factory.create_extension( 'keyUsage', 'cRLSign,keyCertSign', true)
Stamm-CA-Zertifikate sind selbstsigniert.
ca_cert.sign ca_key, OpenSSL::Digest.new('SHA1')
Das CA-Zertifikat wird auf der Festplatte gespeichert, damit es an alle Benutzer der Schlüssel verteilt werden kann, die diese CA signieren wird.
open 'ca_cert.pem', 'w' do |io| io.write ca_cert.to_pem end
Zertifikatssignierungsanforderung
Die CA signiert Schlüssel über eine Zertifikatssignierungsanforderung (CSR). Die CSR enthält die notwendigen Informationen zur Identifizierung des Schlüssels.
csr = OpenSSL::X509::Request.new csr.version = 0 csr.subject = name csr.public_key = key.public_key csr.sign key, OpenSSL::Digest.new('SHA1')
Eine CSR wird auf der Festplatte gespeichert und zur Signatur an die CA gesendet.
open 'csr.pem', 'w' do |io| io.write csr.to_pem end
Zertifikat aus CSR erstellen
Nach Erhalt einer CSR verifiziert die CA diese, bevor sie sie signiert. Eine minimale Verifizierung wäre die Überprüfung der Signatur der CSR.
csr = OpenSSL::X509::Request.new File.read 'csr.pem' raise 'CSR can not be verified' unless csr.verify csr.public_key
Nach der Verifizierung wird ein Zertifikat erstellt, für verschiedene Verwendungszwecke gekennzeichnet, mit dem CA-Schlüssel signiert und an den Anforderer zurückgegeben.
csr_cert = OpenSSL::X509::Certificate.new csr_cert.serial = 0 csr_cert.version = 2 csr_cert.not_before = Time.now csr_cert.not_after = Time.now + 600 csr_cert.subject = csr.subject csr_cert.public_key = csr.public_key csr_cert.issuer = ca_cert.subject extension_factory = OpenSSL::X509::ExtensionFactory.new extension_factory.subject_certificate = csr_cert extension_factory.issuer_certificate = ca_cert csr_cert.add_extension \ extension_factory.create_extension('basicConstraints', 'CA:FALSE') csr_cert.add_extension \ extension_factory.create_extension( 'keyUsage', 'keyEncipherment,dataEncipherment,digitalSignature') csr_cert.add_extension \ extension_factory.create_extension('subjectKeyIdentifier', 'hash') csr_cert.sign ca_key, OpenSSL::Digest.new('SHA1') open 'csr_cert.pem', 'w' do |io| io.write csr_cert.to_pem end
SSL- und TLS-Verbindungen
Mit unserem erstellten Schlüssel und Zertifikat können wir eine SSL- oder TLS-Verbindung herstellen. Ein OpenSSL::SSL::SSLContext wird verwendet, um eine SSL-Sitzung einzurichten.
context = OpenSSL::SSL::SSLContext.new
SSL-Server
Ein SSL-Server benötigt das Zertifikat und den privaten Schlüssel, um sicher mit seinen Clients zu kommunizieren.
context.cert = cert context.key = key
Erstellen Sie dann einen OpenSSL::SSL::SSLServer mit einem TCP-Server-Socket und dem Kontext. Verwenden Sie den SSLServer wie einen gewöhnlichen TCP-Server.
require 'socket' tcp_server = TCPServer.new 5000 ssl_server = OpenSSL::SSL::SSLServer.new tcp_server, context loop do ssl_connection = ssl_server.accept data = ssl_connection.gets response = "I got #{data.dump}" puts response ssl_connection.puts "I got #{data.dump}" ssl_connection.close end
SSL-Client
Ein SSL-Client wird mit einem TCP-Socket und dem Kontext erstellt. OpenSSL::SSL::SSLSocket#connect muss aufgerufen werden, um den SSL-Handshake zu initiieren und die Verschlüsselung zu starten. Für den Client-Socket sind kein Schlüssel und kein Zertifikat erforderlich.
Beachten Sie, dass OpenSSL::SSL::SSLSocket#close den zugrunde liegenden Socket standardmäßig nicht schließt. Setzen Sie OpenSSL::SSL::SSLSocket#sync_close auf true, wenn Sie dies wünschen.
require 'socket' tcp_socket = TCPSocket.new 'localhost', 5000 ssl_client = OpenSSL::SSL::SSLSocket.new tcp_socket, context ssl_client.sync_close = true ssl_client.connect ssl_client.puts "hello server!" puts ssl_client.gets ssl_client.close # shutdown the TLS connection and close tcp_socket
Peer-Verifizierung
Eine unverifizierte SSL-Verbindung bietet nicht viel Sicherheit. Für erhöhte Sicherheit können der Client oder der Server das Zertifikat seines Peers verifizieren.
Der Client kann modifiziert werden, um das Zertifikat des Servers gegen das Zertifikat der Zertifizierungsstelle zu verifizieren.
context.ca_file = 'ca_cert.pem' context.verify_mode = OpenSSL::SSL::VERIFY_PEER require 'socket' tcp_socket = TCPSocket.new 'localhost', 5000 ssl_client = OpenSSL::SSL::SSLSocket.new tcp_socket, context ssl_client.connect ssl_client.puts "hello server!" puts ssl_client.gets
Wenn das Serverzertifikat ungültig ist oder context.ca_file beim Verifizieren von Peers nicht gesetzt ist, wird ein OpenSSL::SSL::SSLError ausgelöst.
Constants
- LIBRESSL_VERSION_NUMBER
-
Versionsnummer der LibreSSL-Bibliothek, die zum Kompilieren der Ruby/OpenSSL-Erweiterung verwendet wurde. Diese kann von der zur Laufzeit verwendeten Version abweichen.
Diese Konstante ist nur definiert, wenn die Erweiterung gegen LibreSSL kompiliert wurde. Die Nummer folgt dem Format:
0xMNNFF00f(Major Minor Fix 00 Status).Siehe auch die Manpage
LIBRESSL_VERSION_NUMBER(3). - OPENSSL_FIPS
-
Boolean, der angibt, ob die OpenSSL-Bibliothek FIPS-fähig ist oder nicht. Immer
truefür OpenSSL 3.0 und höher.Dies ist veraltet und wird in Zukunft entfernt. Siehe auch
OpenSSL.fips_mode. - OPENSSL_LIBRARY_VERSION
-
Versionszeichenkette der OpenSSL-Bibliothek, die zur Laufzeit verwendet wird.
- OPENSSL_VERSION
-
Versionszeichenkette der OpenSSL-Bibliothek, die zum Kompilieren der Ruby/OpenSSL-Erweiterung verwendet wurde. Diese kann von der zur Laufzeit verwendeten Version abweichen.
- OPENSSL_VERSION_NUMBER
-
Versionsnummer der OpenSSL-Bibliothek, die zum Kompilieren der Ruby/OpenSSL-Erweiterung verwendet wurde. Diese kann von der zur Laufzeit verwendeten Version abweichen.
Die Versionsnummer wird in einen einzelnen ganzzahligen Wert kodiert. Die Nummer folgt dem Format
- OpenSSL 3.0.0 oder neuer
-
0xMNN00PP0(Major Minor 00 Patch 0) - OpenSSL 1.1.1 oder früher
-
0xMNNFFPPS(Major Minor Fix Patch Status) - LibreSSL
-
0x20000000(ein fester Wert)
Siehe auch die Manpage
OPENSSL_VERSION_NUMBER(3). - VERSION
-
Die Versionszeichenkette von Ruby/OpenSSL.
Öffentliche Klassenmethoden
Source
# File ext/openssl/lib/openssl/digest.rb, line 63 def Digest(name) OpenSSL::Digest.const_get(name) end
Gibt eine Digest-Unterklasse anhand des Namens zurück.
require 'openssl' OpenSSL::Digest("MD5") # => OpenSSL::Digest::MD5 OpenSSL::Digest("Foo") # => NameError: wrong constant name Foo
Source
static VALUE
ossl_debug_get(VALUE self)
{
return dOSSL;
}
Gibt zurück, ob der Debug-Modus von Ruby/OpenSSL derzeit aktiviert ist.
Source
static VALUE
ossl_debug_set(VALUE self, VALUE val)
{
dOSSL = RTEST(val) ? Qtrue : Qfalse;
return val;
}
Schaltet den Debug-Modus ein oder aus. Im Debug-Modus werden alle Fehler, die der OpenSSL-Fehlerwarteschlange hinzugefügt werden, auf stderr ausgegeben.
Source
static VALUE
ossl_get_errors(VALUE _)
{
VALUE ary;
long e;
ary = rb_ary_new();
while ((e = ERR_get_error()) != 0){
rb_ary_push(ary, rb_str_new2(ERR_error_string(e, NULL)));
}
return ary;
}
Gibt alle verbleibenden Fehler aus der OpenSSL-Thread-lokalen Fehlerwarteschlange zurück und leert die Warteschlange. Dies sollte normalerweise ein leeres Array zurückgeben.
Dies ist für das Debugging von Ruby/OpenSSL gedacht. Wenn Sie hier Fehler sehen, deutet dies wahrscheinlich auf einen Fehler in der Erweiterung hin. Bitte reichen Sie ein Problem unter github.com/ruby/openssl ein.
Zum Debuggen Ihres Programms kann OpenSSL.debug= nützlich sein.
Source
static VALUE
ossl_fips_mode_get(VALUE self)
{
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
VALUE enabled;
enabled = EVP_default_properties_is_fips_enabled(NULL) ? Qtrue : Qfalse;
return enabled;
#elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC)
VALUE enabled;
enabled = FIPS_mode() ? Qtrue : Qfalse;
return enabled;
#else
return Qfalse;
#endif
}
Gibt zurück, ob der FIPS-Modus derzeit aktiviert ist.
Source
static VALUE
ossl_fips_mode_set(VALUE self, VALUE enabled)
{
#if OSSL_OPENSSL_PREREQ(3, 0, 0)
if (RTEST(enabled)) {
if (!EVP_default_properties_enable_fips(NULL, 1)) {
ossl_raise(eOSSLError, "Turning on FIPS mode failed");
}
} else {
if (!EVP_default_properties_enable_fips(NULL, 0)) {
ossl_raise(eOSSLError, "Turning off FIPS mode failed");
}
}
return enabled;
#elif defined(OPENSSL_FIPS) || defined(OPENSSL_IS_AWSLC)
if (RTEST(enabled)) {
int mode = FIPS_mode();
if(!mode && !FIPS_mode_set(1)) /* turning on twice leads to an error */
ossl_raise(eOSSLError, "Turning on FIPS mode failed");
} else {
if(!FIPS_mode_set(0)) /* turning off twice is OK */
ossl_raise(eOSSLError, "Turning off FIPS mode failed");
}
return enabled;
#else
if (RTEST(enabled))
ossl_raise(eOSSLError, "This version of OpenSSL does not support FIPS mode");
return enabled;
#endif
}
Schaltet den FIPS-Modus ein oder aus. Das Einschalten des FIPS-Modus wirkt sich offensichtlich nur auf FIPS-fähige Installationen der OpenSSL-Bibliothek aus. Ein Versuch, dies anderweitig zu tun, führt zu einem Fehler.
Beispiele
OpenSSL.fips_mode = true # turn FIPS mode on OpenSSL.fips_mode = false # and off again
Source
static VALUE
ossl_crypto_fixed_length_secure_compare(VALUE dummy, VALUE str1, VALUE str2)
{
const unsigned char *p1 = (const unsigned char *)StringValuePtr(str1);
const unsigned char *p2 = (const unsigned char *)StringValuePtr(str2);
long len1 = RSTRING_LEN(str1);
long len2 = RSTRING_LEN(str2);
if (len1 != len2) {
ossl_raise(rb_eArgError, "inputs must be of equal length");
}
switch (CRYPTO_memcmp(p1, p2, len1)) {
case 0: return Qtrue;
default: return Qfalse;
}
}
Konstante Zeit-Speichervergleich für Zeichenketten fester Länge, wie z.B. Ergebnisse von HMAC-Berechnungen.
Gibt true zurück, wenn die Zeichenketten identisch sind, false, wenn sie die gleiche Länge haben, aber nicht identisch sind. Wenn die Länge unterschiedlich ist, wird ein ArgumentError ausgelöst.
Source
# File ext/openssl/lib/openssl.rb, line 36 def self.secure_compare(a, b) hashed_a = OpenSSL::Digest.digest('SHA256', a) hashed_b = OpenSSL::Digest.digest('SHA256', b) OpenSSL.fixed_length_secure_compare(hashed_a, hashed_b) && a == b end
Konstante Zeit-Speichervergleich. Eingaben werden mittels SHA-256 gehasht, um die Länge des Geheimnisses zu maskieren. Gibt true zurück, wenn die Zeichenketten identisch sind, false andernfalls.
Diese Methode ist aufgrund des SHA-256-Hashens aufwendig. In den meisten Fällen, in denen die Eingabelängen bekannt sind oder nicht sensibel sind, sollte OpenSSL.fixed_length_secure_compare stattdessen verwendet werden.
Private Instanzmethoden
Source
# File ext/openssl/lib/openssl/digest.rb, line 63 def Digest(name) OpenSSL::Digest.const_get(name) end
Gibt eine Digest-Unterklasse anhand des Namens zurück.
require 'openssl' OpenSSL::Digest("MD5") # => OpenSSL::Digest::MD5 OpenSSL::Digest("Foo") # => NameError: wrong constant name Foo