Je travaille sur un projet que je souhaite ajouter SSL à, j'ai donc créé une implémentation de test client / serveur simple pour voir si elle fonctionnait et que je reçois une noschalgorithmexception. Ce qui suit est mon code de serveur qui jette l'exception: La stacktrace i get est: p> J'ai essayé de remplacer "TLS" avec "SSL" et j'ai toujours eu la même exception. Cela n'avait pas de sens pour moi. Comment TLS et SSL peuvent-ils ne pas être pris en charge? C'est mon premier temps d'essayer de mettre en œuvre SSL et il semble difficile de trouver de bonnes ressources à ce sujet avec des exemples de code bien expliqués. Quelqu'un peut-il me dire pourquoi je reçois cette exception ou soulignez quelque chose de mal avec mon code? P> p>
3 Réponses :
Il y a un certain nombre de problèmes:
TLS code> (Sécurité de la couche de transport), pas TSL code> (pour le SSLContext code>). LI>
- Je suggère d'utiliser la valeur par défaut ici:
TrustManagerFactory TMF = TrustManagerFactory.getinstance (FredManagerFactory.getDefaultalgorithm ()) Code> (La valeur par défaut sera PKIX CODE> SUR LE Oracle JRE` ) li>
- (
EDIT: strong>) La valeur par défaut KeyManagerFactory code> est sunx509 code> ( tls code> n'existe pas ici). Encore une fois, utilisez getDefaultalgorithm () code>. Li>
- Vous devez fermer votre
FileInputStream code> une fois que vous les avez lu. Li>
- Ce n'est pas clair pourquoi vous avez à la fois un client et un magasin de clés de serveur au même endroit. Ceux-ci devraient être deux programmes: un pour le client et le serveur (et
SetNeedClientauthuth (true) code> est uniquement utile sur le côté serveur). Il serait plus clair de l'appeler autre chose que "client client" si c'est effectivement votre clé de clés. (En outre, puisque vous semblez apprendre à faire ce travail, je suggérerais d'essayer d'abord d'essayer sans authentification de certificat client, auquel cas, le serveur n'aura pas besoin d'une dépôt de fiducies: Utilisez null code> En tant que deuxième paramètre de sslContext.init (...) code> pour utiliser la valeur par défaut.) li>
- Ne donnez pas de clé de clés de serveur au client. Seuls l'exportation de son certificat en un nouveau keyStore que vous utiliserez comme magasin de fiducie. Chaque entité (client et serveur) devrait conserver ses propres clés privées privées. Li>
- Ce n'est pas tant la clé publique em> (seulement) de la partie distante que vous souhaitez dans votre magasin Trust-Store: ça va être son certificat em>. Assurez-vous de ne pas importer que sa clé publique, mais tout le certificat. Li>
- Pour clarifier, conservez les extensions appropriées dans vos fichiers: Utilisez
.jks code> pour votre jks code> KeyStore, cela vous permettra de sauvegarder des maux de tête plus tard. Li>
- Vous pouvez utiliser
null code> pour le SE SIERURANDOM code> dans SSLContext.init (...) code>: Cela utilisera la valeur par défaut en fonction de la valeur Fournisseur de sécurité. LI>
ul> Quelque chose comme ça devrait mieux fonctionner: p> xxx pré> p>
K j'ai édité mon message pour ajouter ce changement. J'ai toujours la même exception même lorsque j'utilise "TLS"
Si vous êtes vraiment inquiet pour les mots de passe, vous devez utiliser un char [] code> directement ou comme rappel du mot de passe, et ne jamais coder votre mot de passe de toute façon dans une application réelle (voir
Comme une note latérale, en attente de readline code> pour retourner null code> n'est pas un bon moyen de savoir quand arrêter de lire (de n'importe quelle sorte de prise), voir la discussion ici: Stackoverflow.com/a/6425509/372643
J'ai changé mon code pour utiliser TrustManagerFactory.getDefaultalgorithM () et KeyManagerFactory.getDefaultalgorithm () et qui a eu le travail. La raison pour laquelle j'ai les deux keystores ici est que le serveur a: serveur.private et client.Public, tandis que le client aura client.private et Server.Public. BTW, j'ai utilisé ce site comme référence pour mon code, je ne sais pas à quel point il est fiable, mais c'est le meilleur que je pouvais trouver: www.ibm.com/developerworks/java/Tutorials/j-jsse/index.html
Il a dit sunx509 code> pour le KMF, pas tls code>. Il utilise également une version assez ancienne de Java, la nouvelle valeur par défaut du TMF est pKix code>. (Je ne suis toujours pas convaincu de la convention de dénomination du fichier KeyStore dans cet article.)
Au lieu d'utiliser .private et .Public devrais-je simplement les faire .JKS? En outre, en référence à l'article sur la fermeture SSLSocket correctement, comment détecterai-je le close_notify sur le serveur lorsque le client appelle socket.close () code>?
À propos des fichiers, vous pourriez également simplement ajouter .jks code>, oui. À propos de la fermeture des sockets, c'est un problème de réseautage plus général: vous ne pouvez généralement pas distinguer les prises silencieuses et anormalement fermées. C'est pourquoi les protocoles utilisent un indicateur pour indiquer la quantité de données qu'ils vont envoyer (et vous devez généralement définir une valeur du délai d'expiration): Par exemple, http a longueur de contenu code> et codage de transfert de contenu dire au destinataire lorsque le message attendu est terminé. D'autres protocoles ont d'autres délimiteurs.
C'est le problème avec mon programme. Plusieurs clients se connecteront au serveur, ils enverront de nombreux messages jusqu'à ce que le client se déconnecte. Je suppose que vous pouvez penser à cela un peu comme une salle de discussion multi-utilisateurs. Donc, depuis que je ne sais pas avant de la main combien de données ou combien de messages seront envoyés, je viens de vérifier la fin de la bufferedreader. Utiliser cette méthode toujours considérée comme une mauvaise pratique ou est-ce acceptable?
Ne vérifiez pas la fin du lecteur. Cela pourrait fonctionner la plupart du temps afin de ne pas voir le problème, mais étudiez d'autres protocoles. HTTP, POP, IMAP, SMTP ont tous une forme de délimiteurs à indiquer à la partie distante lorsqu'elles sont terminées (et en attente d'un autre message). Chaque fois que vous envoyez un nouveau message dans votre chat (qui peut être représenté ou non par un "message" au niveau de votre protocole d'application), utilisez un indicateur pour dire quand il va se terminer.
Le nom de SSLContext correct est "TLS". Une liste des noms d'algorithme standard peut être trouvé ici. p>
C'était un mathype et a été corrigé. Je reçois toujours l'exception avec "TLS"
Voir Modification de Bruno à sa réponse concernant la clé KeyManagerFactory, ce serait votre autre problème.
Voir http: // docs .Oracle.com / Javase / 6 / Documents / Technotes / Guides / Security / JSSE / JSSEFGUIDE.HTML # SupportClasses Pour des exemples et pour les noms de l'algorithme pris en charge. Il semble que "Sunx509" et "Newsunx509" sont les algorithmes soutenus par KeyManagerFactory. Et le protocole est nommé TLS, pas TSL. P>
Encore une fois, c'était un mistpe et a été corrigé. Je reçois toujours l'exception avec "TLS"
Avez-vous lu ma réponse? Il semble que "Sunx509" et "Newsunx509" sont les algorithmes supportés par KeyManagerFactory i>.
+ 1'ed (comme j'avais fait une faute de frappe dans ma réponse initiale x509 code> -> sunx509 code>). @ Mattl922: getDefaultalgorithm () code> est souvent le pari le plus sûr.