J'ai un client de service Web Java, qui consomme un service Web via HTTPS.
import javax.xml.ws.Service;
@WebServiceClient(name = "ISomeService", targetNamespace = "http://tempuri.org/", wsdlLocation = "...")
public class ISomeService
extends Service
{
public ISomeService() {
super(__getWsdlLocation(), ISOMESERVICE_QNAME);
}
Lorsque je me connecte à l'URL du service ( https://AAA.BBB.CCC.DDD:9443/ISomeService
), j'obtiens l'exceptionjava.security.cert.CertificateException: No subject alternative names present
.
Pour le réparer, j'ai d'abord couru openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt
et j'ai obtenu le contenu suivant dans le fichier certs.txt
:
CONNECTED(00000003)
---
Certificate chain
0 s:/CN=someSubdomain.someorganisation.com
i:/CN=someSubdomain.someorganisation.com
-----BEGIN CERTIFICATE-----
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
-----END CERTIFICATE-----
---
Server certificate
subject=/CN=someSubdomain.someorganisation.com
issuer=/CN=someSubdomain.someorganisation.com
---
No client certificate CA names sent
---
SSL handshake has read 489 bytes and written 236 bytes
---
New, TLSv1/SSLv3, Cipher is RC4-MD5
Server public key is 512 bit
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : RC4-MD5
Session-ID: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Session-ID-ctx:
Master-Key: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Key-Arg : None
Start Time: 1382521838
Timeout : 300 (sec)
Verify return code: 21 (unable to verify the first certificate)
---
AFAIK, maintenant je dois
- extraire la partie
certs.txt
entre-----BEGIN CERTIFICATE-----
et-----END CERTIFICATE-----
, - modifiez-le pour que le nom du certificat soit égal à
AAA.BBB.CCC.DDD
et - puis importez le résultat en utilisant
keytool -importcert -file fileWithModifiedCertificate
(oùfileWithModifiedCertificate
est le résultat des opérations 1 et 2).
Est-ce correct?
Si tel est le cas, comment puis-je faire en sorte que le certificat de l'étape 1 fonctionne avec une adresse IP (AAA.BBB.CCC.DDD
) ?
Mise à jour 1 (23.10.2013 15:37 MSK): Dans une réponse à une question similaire , j'ai lu ce qui suit:
Si vous ne contrôlez pas ce serveur, utilisez son nom d'hôte (à condition qu'il y ait au moins un CN correspondant à ce nom d'hôte dans le certificat existant).
Que signifie exactement «utiliser»?
la source
J'ai le même problème et résolu avec ce code. J'ai mis ce code avant le premier appel à mes webservices.
C'est simple et fonctionne bien.
Voici la source originale.
la source
return hostname.equals("localhost");
, si c'est ce que vous voulez faire. Leif
est complètement superflu.HttpsURLConnection connection = (HttpsURLConnection) obj.openConnection();
. De plus, cela ignore-t-il chaque certificat? Depuis que j'ai vu qu'une telle solution de contournement est vulnérable à la sécurité. Je vous remercie!C'est une vieille question, mais j'ai eu le même problème lors du passage du JDK 1.8.0_144 au jdk 1.8.0_191
Nous avons trouvé un indice dans le changelog:
Changelog
nous avons ajouté la propriété système supplémentaire suivante, qui a aidé dans notre cas à résoudre ce problème:
la source
La vérification de l'identité du certificat est effectuée par rapport à ce que le client demande.
Lorsque votre client utilise
https://xxx.xxx.xxx.xxx/something
(oùxxx.xxx.xxx.xxx
est une adresse IP), l'identité du certificat est vérifiée par rapport à cette adresse IP (en théorie, en utilisant uniquement une extension IP SAN).Si votre certificat n'a pas de SAN IP, mais des SAN DNS (ou s'il n'y a pas de SAN DNS, un nom commun dans le DN du sujet), vous pouvez le faire fonctionner en faisant en sorte que votre client utilise à la place une URL avec ce nom d'hôte (ou un nom d'hôte pour lequel le certificat serait valide, s'il y a plusieurs valeurs possibles). Par exemple, si votre certificat a un nom pour
www.example.com
, utilisezhttps://www.example.com/something
.Bien sûr, vous aurez besoin de ce nom d'hôte pour résoudre cette adresse IP.
En outre, s'il existe des SAN DNS, le CN dans le DN du sujet sera ignoré, utilisez donc un nom qui correspond à l'un des SAN DNS dans ce cas.
la source
http://www.example.com/someservice
. Est-il correct que pour que le certificat fonctionne avec une adresse IP (https://AAA.BBB.CCC.DDD:9443/ISomeService
), je dois définir tous lesCN
champs surAAA.BBB.CCC.DDD
(remplacersomeSubdomain.someorganisation.com
parAAA.BBB.CCC.DDD
dans le fichier ci-dessus) et importer le fichier de certificat résultant?/etc/hosts
fichier ou équivalentPour importer le certificat:
openssl s_client -showcerts -connect AAA.BBB.CCC.DDD:9443 > certs.txt
Cela extraira les certificats au format PEM.openssl x509 -in certs.txt -out certs.der -outform DER
sudo keytool -importcert -file certs.der -keystore <path-to-cacerts>
mot de passe par défaut de cacerts est «changeit».Si le certificat est émis pour un FQDN et que vous essayez de vous connecter par adresse IP dans votre code Java, cela devrait probablement être corrigé dans votre code plutôt que de jouer avec le certificat lui-même. Modifiez votre code pour vous connecter par FQDN. Si le FQDN ne peut pas être résolu sur votre machine de développement, ajoutez-le simplement à votre fichier hosts ou configurez votre machine avec un serveur DNS capable de résoudre ce FQDN.
la source
J'ai résolu ce problème de la bonne manière en ajoutant les noms alternatifs des sujets dans le certificat plutôt qu'en apportant des modifications au code ou en désactivant SSL contrairement à ce que d'autres réponses suggèrent ici. Si vous voyez clairement, l'exception indique que les "noms alternatifs des sujets manquent", la bonne façon devrait donc être de les ajouter
Veuillez regarder ce lien pour comprendre étape par étape .
L'erreur ci-dessus signifie que votre fichier JKS n'a pas le domaine requis sur lequel vous essayez d'accéder à l'application.Vous devrez utiliser Open SSL et l'outil clé pour ajouter plusieurs domaines
echo '[ subject_alt_name ]' >> openssl.cnf
echo 'subjectAltName = DNS:example.mydomain1.com, DNS:example.mydomain2.com, DNS:example.mydomain3.com, DNS: localhost'>> openssl.cnf
openssl req -x509 -nodes -newkey rsa:2048 -config openssl.cnf -extensions subject_alt_name -keyout private.key -out self-signed.pem -subj '/C=gb/ST=edinburgh/L=edinburgh/O=mygroup/OU=servicing/CN=www.example.com/[email protected]' -days 365
Exportez le fichier de clé publique (.pem) au format PKS12. Cela vous demandera le mot de passe
Créer un.JKS à partir d'un PEM auto-signé (Keystore)
Générer un certificat à partir du Keystore ou du fichier JKS ci-dessus
Étant donné que le certificat ci-dessus est auto-signé et n'est pas validé par l'autorité de certification, il doit être ajouté dans Truststore (fichier Cacerts à l'emplacement ci-dessous pour MAC, pour Windows, découvrez où votre JDK est installé.)
Réponse originale publiée sur ce lien ici .
la source
Vous ne voudrez peut-être pas désactiver toutes les vérifications ssl et vous pouvez donc simplement désactiver la vérification du nom d'hôte via ce qui est un peu moins effrayant que l'alternative:
[ÉDITER]
Comme mentionné par conapart3
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
est maintenant obsolète, il peut donc être supprimé dans une version ultérieure, vous pourriez donc être obligé à l'avenir de lancer le vôtre, même si je dirais toujours que je m'éloignerais de toute solution où toute vérification est désactivée.la source
SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER
est désormais obsolète.mon problème avec cette erreur a été résolu en utilisant l'URL complète "qatest.ourCompany.com/webService" au lieu de simplement "qatest / webService". La raison était que notre certificat de sécurité avait un caractère générique, à savoir "* .ourCompany.com". Une fois que j'ai mis l'adresse complète, l'exception a disparu. J'espère que cela t'aides.
la source
J'y ai déjà répondu dans https://stackoverflow.com/a/53491151/1909708 .
Cela échoue car ni le nom commun du certificat (
CN
dans la certificationSubject
) ni aucun des autres noms (Subject Alternative Name
dans le certificat) ne correspondent au nom d'hôte ou à l'adresse IP cible.Par exemple, à partir d'une JVM, lorsque vous essayez de vous connecter à une adresse IP (
WW.XX.YY.ZZ
) et non au nom DNS ( https://stackoverflow.com ), la connexion HTTPS échouera car le certificat stocké dans le truststore javacacerts
attend un nom commun (ou un autre nom du certificat comme stackexchange.com ou * .stackoverflow.com etc.) pour correspondre à l'adresse cible.Veuillez vérifier: https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html#HostnameVerifier
Ci-dessus, passé un
HostnameVerifier
objet implémenté qui est toujours retournétrue
:la source
Pour Spring Boot
RestTemplate
:org.apache.httpcomponents.httpcore
dépendanceutiliser
NoopHostnameVerifier
pour l'usine SSL:la source
Je suis arrivé à cette question après avoir reçu le même message d'erreur. Cependant, dans mon cas, nous avions deux URL avec des sous-domaines différents ( http://example1.xxx.com/someservice et http://example2.yyy.com/someservice ) qui étaient dirigés vers le même serveur. Ce serveur n'avait qu'un seul certificat générique pour le domaine * .xxx.com. Lors de l'utilisation du service via le deuxième domaine, le certificat trouvé (* .xxx.com) ne correspond pas au domaine demandé (* .yyy.com) et l'erreur se produit.
Dans ce cas, nous ne devrions pas essayer de corriger un tel message d'erreur en réduisant la sécurité SSL, mais nous devrions vérifier le serveur et les certificats qu'il contient.
la source
la source
Je passais par SSL 2 voies dans springboot. J'ai fait tout le serveur de tomcat de service de configuration correct et l'appelant de service RestTemplate. mais j'obtenais une erreur comme "java.security.cert.CertificateException: aucun autre nom de sujet présent"
Après avoir parcouru les solutions, j'ai trouvé que JVM a besoin de ce certificat, sinon cela donne une erreur de négociation.
Maintenant, comment ajouter ceci à JVM.
allez dans le fichier jre / lib / security / cacerts. nous devons ajouter notre fichier de certificat de serveur à ce fichier cacerts de jvm.
Commande pour ajouter un certificat de serveur au fichier cacerts via la ligne de commande dans Windows.
C: \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ security> keytool -import -noprompt -trustcacerts -alias sslserver -file E: \ spring_cloud_sachin \ ssl_keys \ sslserver.cer -keystore cacerts -storepass changeit
Vérifiez que le certificat du serveur est installé ou non:
C: \ Program Files \ Java \ jdk1.8.0_191 \ jre \ lib \ security> keytool -list -keystore cacerts
vous pouvez voir la liste des certificats installés:
pour plus de détails: https://sachin4java.blogspot.com/2019/08/javasecuritycertcertificateexception-no.html
la source
ajoutez l'entrée d'hôte avec l'ip correspondant au CN dans le certificat
CN = someSubdomain.someorganisation.com
maintenant, mettez à jour l'adresse IP avec le nom CN où vous essayez d'accéder à l'url.
Cela a fonctionné pour moi.
la source
la source
Lorsque vous avez un certificat avec à la fois CN et SAN (Subject Alternative Names), si vous faites votre demande en fonction du contenu CN, ce contenu particulier doit également être présent sous SAN, sinon il échouera avec l'erreur en question.
Dans mon cas, le CN avait quelque chose, le SAN avait autre chose. J'ai dû utiliser l'URL SAN, puis cela a très bien fonctionné.
la source
Ajoutez votre adresse IP dans le fichier hosts qui se trouve dans le dossier C: \ Windows \ System32 \ drivers \ etc. Ajoutez également l'IP et le nom de domaine de l'adresse IP. exemple: aaa.bbb.ccc.ddd [email protected]
la source
J'ai résolu le problème de la manière suivante.
1. Créer une classe. La classe a des implémentations vides
2. Créer une méthode
la source