2010-01-23 9 views
7

Ich versuche nur, mich um SSL zu kümmern.Mit einem selbstsignierten Zertifikat

Ich habe einen Jetty-Server auf meinem localhost eingerichtet und mein eigenes Zertifikat mit Keytool generiert.

Jetzt, wenn ich zu https://localhost:8443/ gehe, bekomme ich die kann diesen Zertifikatsfehler nicht vertrauen.

Ich benutze

keytool -export -alias pongus -keystore Schlüsselspeicher -datei certfile.cer

Um das Zertifikat zu erstellen, was ich denke, ist das, was der Client mit dem Server authentifizieren muss. (Dies ist, wo ich sehr falsch sein könnte!)

Ich habe den folgenden Ruby-Code:

require 'net/https' 
require 'openssl' 

require 'open-uri' 

puts 'yay' if File.exists?('certfile.cer') 

uri = URI.parse("https://localhost:8443/") 
http_session = Net::HTTP.new(uri.host, uri.port) 
http_session.use_ssl = true 
http_session.verify_mode = OpenSSL::SSL::VERIFY_PEER 
http_session.ca_file = 'certfile.cer' 
res = http_session.start do |http| 
    # do some requests here 
    http.get('/') 
end 

Dies gilt print 'yay', so die certfile.cer Datei existiert.

Aber ich bekomme die Fehler

/Applications/NetBeans/NetBeans 6.8.app/Contents/Resources/NetBeans/ruby2/jruby-1.4.0/lib/ruby/1.8/net/http.rb:586 warning: can't set verify locations 
/Applications/NetBeans/NetBeans 6.8.app/Contents/Resources/NetBeans/ruby2/jruby-1.4.0/lib/ruby/1.8/net/http.rb:586:in `connect': certificate verify failed (OpenSSL::SSL::SSLError) 

Irgendwelche Ideen, was ich falsch mache?

EDIT

ich mag es bekommen, so garantiere ich, dass ich auf den richtigen Server anschließe, und der Server kann garantieren, dass es mich zu ihm verbinden, ohne dass zwischen Manipulation in. Ich entwickle sowohl den Server als auch den Client.

Antwort

5

Ihr Client benötigt Zugriff auf seinen privaten Schlüssel .

Sie benötigen keinen privaten Schlüssel für die Überprüfung des Serverzertifikats. Sie benötigen lediglich das Zertifikat selbst, das den öffentlichen Schlüssel enthält. Nur der Server verfügt über den privaten Schlüssel. Gut beschrieben hier http://www.helpbytes.co.uk/https.php und hier http://www.verisign.com/ssl/ssl-information-center/how-ssl-security-works/

Meine Empfehlung ist einfach. Überprüfen Sie, ob Ihr Zertifikat korrekt ist.

openssl x509 -text -in mycert.crt 

Auch wenn Sie Zugriff auf den Server haben, können Sie explizit überprüfen, ob das Zertifikat und den Schlüssel (in httpd-Konfiguration verwendet) korrekt sind (Ursachen): http://kb.wisc.edu/middleware/page.php?id=4064 Bitte beachten Sie, diese explizite Kontrolle ist auf dem Server ausgeführt wird. Gib niemals den privaten Schlüssel aus. Diese Überprüfung kann nur vom Administrator vorgenommen werden, um zu überprüfen, ob der httpd nicht falsch konfiguriert wurde.

(openssl x509 -noout -modulus -in server.pem | openssl md5 ;\ 
    openssl rsa -noout -modulus -in server.key | openssl md5) | uniq 

Sie können die SSL-Zertifikatkommunikation auch mit dem Standardbefehl openssl debuggen. Geben Sie diesen Befehl aus, warten Sie einige Sekunden, geben Sie QUIT ein und drücken Sie die Eingabetaste. Sie sehen das Zertifikat, das der Server sendet.

Versuchen Sie auch, das Zertifikat in Ihren Browser zu importieren und auf die URL-Ressource zuzugreifen. Der Browser kann dies überprüfen, indem er auf https (Firefox und Chrome) klickt. Dann sehen Sie das Zertifikat selbst und die Gültigkeitsinformationen.

Alles oben erwähnte war alles über das Serverzertifikat. Dies ist nur ein Teil des Problems. "Ich verbinde mich mit dem richtigen Server, und der Server kann garantieren, dass es mich verbindet" Actully in Ihrem Code über Sie nur für den Server cert. Jetzt. Wenn Sie ein Client-Zertifikat (der zweite Teil Ihrer Aussage) wollen, als Sie brauchen dies in Ruby:

File.open("client_certificate.pem", 'rb') { |f| cert = f.read } 
File.open("client_key.pem", 'rb') { |f| key = f.read } 
http_session.cert = OpenSSL::X509::Certificate.new(cert) 
http_session.key = OpenSSL::PKey::RSA.new(key, nil) 

Dies ist, wie Client-Zertifikat sollte in Ruby verwendet werden. Wenn Ihr privater Schlüssel mit einem Passwort verschlüsselt ist, übergeben Sie ihn einfach im zweiten Argument des RSA-Konstruktors.

Ich empfehle dringend, Server-Zertifikat arbeiten (Ihren Code) und dann mit Client-Zertifikat zu starten. Bitte beachten Sie, dass Sie Ihren aktuellen Code (ca_cert, Validierungskonstante) beibehalten und die obigen vier Zeilen hinzufügen.

Hoffe, das hilft.

+0

In jedem Fall brauchen Sie keinen privaten Schlüssel auf Ihrem Client. Niemals. Zeitraum. – lzap

+0

Eine weitere Sache.Sie können das Zertifikat auch mit Firefox oder IE EXPORTIEREN! Es ist sehr einfach. Greifen Sie auf die Seite zu und exportieren Sie sie in eine PEM-Datei. Sie können das mit Ruby verwenden. Ich habe das mehrmals gemacht. Funktioniert! – lzap

+0

Falsch. Sie verstehen einfach nicht die SSL-Client-Authentifizierung, die der Fragesteller eindeutig angegeben hat. "... was ich denke ist, was der Client benötigt, um sich mit dem Server zu authentifizieren ..." sowie der Kommentar in der Bearbeitung zeigen dies an. –

-8

ändern

http_session.verify_mode = OpenSSL::SSL::VERIFY_PEER 

zu

http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE 

Sobald Sie das tun, wird die SSL ordnungsgemäß funktionieren. Ich habe das mehrfach in meinen Entwicklungsumgebungen genutzt, funktioniert immer einwandfrei.

+1

Vielen Dank, aber ich möchte nicht, dass es die Überprüfung ausblendet. . ;-) –

+0

Eugene, was denkst du ist dein kleiner Trick? –

+0

Es tut mir leid, dass es so lange gedauert hat, darauf zu antworten. Wenn VERIFY_PEER versucht, das CERT gegen einen bekannten SSL-Aussteller zu validieren, müssen Sie VERIFY_NONE verwenden, um diese Prüfung zu umgehen. Es validiert das Zertifikat nicht per se, sondern validiert den Aussteller des Zertifikats. Da selbstsignierte Zertifikate keinen bekannten Aussteller haben, schlägt die Prüfung fehl. – Eugene

0

Ihr Client benötigt Zugriff auf seinen privaten Schlüssel. Der private Schlüssel befindet sich nicht im Zertifikat, das Zertifikat enthält nur den öffentlichen Schlüssel. Tut mir leid, ich weiß Ruby nicht, aber eine übliche Technik besteht darin, den privaten Schlüssel und das Zertifikat in einer einzelnen PKCS # 12, aka p12, Datei zu bündeln und diese der Krypto-Bibliothek zur Verfügung zu stellen.

+0

Nice one, das ist gute Information, um mir etwas zu geben, weiterzugehen! Ich gehe zurück zur Keytool-Dokumentation. Danke –

+0

Ruby akzeptiert PEM. Theres keine Notwendigkeit für p12 und privaten Schlüssel überhaupt. Es ist ein Sicherheitsloch, um den PK herauszugeben :-) – lzap

+1

@Izap: Es gibt keinen privaten Schlüssel, es gibt zwei: einen für den Client und einen für den Server. Deshalb habe ich gesagt, dass der Client Zugriff auf den privaten Schlüssel * ITS * benötigt, nicht auf den Server. –