2010-01-23 7 views
7

J'essaie juste de comprendre le protocole SSL.Utilisation d'un certificat auto-signé

J'ai configuré un serveur Jetty sur mon hôte local et généré mon propre certificat en utilisant Keytool.

Maintenant, quand je vais à https://localhost:8443/ je reçois le ne peut pas faire confiance à cette erreur de certificat.

J'utilise

keytool -export -alias pongus -keystore keystore -file certfile.cer

Pour créer le certificat que je pense est ce que le client a besoin d'authentifier auprès du serveur. (C'est là que je pourrais être très mal!)

J'ai le code ruby ​​suivant:

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 

Cela ne print 'yay', de sorte que le fichier certfile.cer existe.

Mais je reçois les erreurs

/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) 

Toutes les idées que je fais mal?

EDIT

Je veux donc je vous garantis que je me connecte au bon serveur, et le serveur peut garantir qu'il me se connecte, sans aucune altération entre les deux. Je développe à la fois le serveur et le client.

Répondre

5

Votre client doit avoir accès à sa clé privée .

Vous n'avez pas besoin de la clé privée pour la vérification du certificat de serveur. Tout ce dont vous avez besoin est le certificat lui-même qui contient la clé publique. Seul le serveur a la clé privée. Bien décrit ici http://www.helpbytes.co.uk/https.php et ici http://www.verisign.com/ssl/ssl-information-center/how-ssl-security-works/

Ma recommandation est simple. Vérifiez votre certificat est correct.

openssl x509 -text -in mycert.crt 

Aussi, si vous avez accès au serveur, vous pouvez valider si le explicitement certificat et la clé (utilisé dans la configuration de httpd) sont corrects (correspondances): http://kb.wisc.edu/middleware/page.php?id=4064 S'il vous plaît noter que ceci est vérification explicite couru sur le serveur. Ne donnez jamais la clé privée. Cette vérification peut être effectuée uniquement par l'administrateur pour vérifier si le fichier httpd n'a pas été mal configuré.

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

Vous pouvez également déboguer la communication du certificat SSL à l'aide de la commande standard openssl. Exécutez cette commande, attendez quelques secondes, puis tapez QUIT et appuyez sur Entrée. Vous verrez le certificat que le serveur envoie.

openssl s_client -connect your.server.com:443 

Essayez également d'importer le certificat dans votre navigateur et d'accéder à la ressource URL. Le navigateur est capable de le valider en cliquant sur https (Firefox et Chrome). Ensuite, vous verrez le certificat lui-même et les informations de validité.

Tout ce qui précède concernait le certificat de serveur . Ce n'est qu'une partie du problème. "Je me connecte au bon serveur, et le serveur peut garantir que je me connecte à lui" Actully dans votre code ci-dessus seulement vous vérifiez le certificat du serveur. À présent. Si vous voulez un certificat client (la deuxième partie de votre déclaration) que vous avez besoin dans ce 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) 

Voici comment client cert doit être utilisé dans Ruby. Si votre clé privée est chiffrée avec un mot de passe, passez-la à la place dans le second argument du constructeur RSA.

Je recommande fortement de faire fonctionner le certificat de serveur (votre code) et ensuite commencer avec le certificat client. Veuillez noter que vous conservez votre code actuel (ca_cert, constante de validation) et ajoutez les quatre lignes ci-dessus.

Espérons que cela aide.

+0

Dans tous les cas, vous n'avez pas besoin de clé privée sur votre client. Plus jamais. Période. – lzap

+0

Encore une chose.Vous pouvez également EXPORTER le certificat en utilisant Firefox ou IE! C'est très simple. Accédez à la page et exportez-la dans un fichier PEM. Vous pouvez utiliser celui-là avec Ruby. Je l'ai fait plusieurs fois. Travaux! – lzap

+0

Incorrect. Vous ne comprenez simplement pas l'authentification du client SSL, ce que le demandeur a clairement déclaré avoir besoin. "... ce que je pense est ce que le client a besoin de s'authentifier avec le serveur ..." ainsi que le commentaire dans le montage l'indiquent. –

-8

changement

http_session.verify_mode = OpenSSL::SSL::VERIFY_PEER 

à

http_session.verify_mode = OpenSSL::SSL::VERIFY_NONE 

Une fois que vous faites cela, le SSL fonctionne correctement. Je l'ai utilisé plusieurs fois dans mes environnements de développement, fonctionne toujours parfaitement.

+1

Merci, mais je ne veux pas éviter la vérification. . ;-) –

+0

Eugène, que penses-tu de ton petit tour? –

+0

Je suis désolé, il a fallu si longtemps pour répondre à cela. Comme VERIFY_PEER essaie de valider le certificat par rapport à un émetteur SSL connu, vous devez utiliser VERIFY_NONE pour contourner cette vérification. Ce n'est pas valider le certificat en soi, mais valider l'émetteur du certificat. Comme les certificats autosignés n'ont pas d'émetteur connu, la vérification échoue. – Eugene

0

Votre client doit avoir accès à sa clé privée. La clé privée n'est pas dans le certificat, le certificat contient uniquement la clé publique. Désolé, je ne connais pas ruby, mais une technique courante consiste à regrouper la clé privée et le certificat dans un seul fichier PKCS # 12, alias p12, et à le fournir à la bibliothèque de chiffrement.

+0

Nice, c'est une bonne information pour me donner quelque chose à faire! Je reviens à la documentation de keytool. Merci –

+0

Ruby accepte le PEM. Theres pas besoin de p12 et clé privée du tout. C'est un trou de sécurité pour distribuer le PK :-) – lzap

+1

@Izap: Il n'y a pas de clé privée, il y en a deux: une pour le client et une pour le serveur. C'est pourquoi j'ai dit que le client avait besoin d'accéder à la clé privée * ITS *, pas au serveur. –