Atualizei do Java 1.6 para o Java 1.7 hoje. Desde então, ocorre um erro quando tento estabelecer uma conexão com meu servidor da Web por SSL:
javax.net.ssl.SSLProtocolException: handshake alert: unrecognized_name
at sun.security.ssl.ClientHandshaker.handshakeAlert(ClientHandshaker.java:1288)
at sun.security.ssl.SSLSocketImpl.recvAlert(SSLSocketImpl.java:1904)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:1027)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1262)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1289)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1273)
at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:523)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:185)
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1296)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getInputStream(HttpsURLConnectionImpl.java:254)
at java.net.URL.openStream(URL.java:1035)
Aqui está o código:
SAXBuilder builder = new SAXBuilder();
Document document = null;
try {
url = new URL(https://some url);
document = (Document) builder.build(url.openStream());
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(DownloadLoadiciousComputer.class.getName()).log(Level.SEVERE, null, ex);
}
É apenas um projeto de teste, é por isso que permito e uso certificados não confiáveis com o código:
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
Logger.getLogger(DownloadManager.class.getName()).log(Level.SEVERE, null, e);
}
Tentei conectar-me com sucesso a https://google.com . onde está minha culpa?
Obrigado.
Eu tinha o que acredito que seja o mesmo problema. Descobri que precisava ajustar a configuração do Apache para incluir um ServerName ou ServerAlias para o host.
Este código falhou:
E esse código funcionou:
O Wireshark revelou que, durante o TSL / SSL Hello, o alerta de aviso (Nível: Aviso, Descrição: Nome não reconhecido), o Server Hello estava sendo enviado do servidor para o cliente. Foi apenas um aviso, no entanto, o Java 7.1 respondeu imediatamente de volta com uma "Descrição fatal: mensagem inesperada", que suponho que as bibliotecas Java SSL não gostam de ver o aviso de nome não reconhecido.
No Wiki sobre Transport Layer Security (TLS):
112 Nome não reconhecido, avisando apenas TLS; O Indicador de Nome do Servidor do cliente especificou um nome de host não suportado pelo servidor
Isso me levou a olhar para os meus arquivos de configuração do Apache e descobri que, se eu adicionasse um ServerName ou ServerAlias para o nome enviado do lado do cliente / java, funcionaria corretamente sem erros.
fonte
ServerAlias
funcionou para mim. Eu tinha visto o mesmo alerta TLS no Wireshark.ServerName
s, o Apache responde com um alerta deunrecognized_name
aviso (que também pode ser um alerta fatal ). O RFC 6066 diz precisamente isso sobre este tópico: " NÃO É RECOMENDADO enviar um alerta unrecognized_name (112) no nível do aviso, porque o comportamento do cliente em resposta a alertas no nível do aviso é imprevisível ". O único erro cometido por esse funcionário é assumir que esse foi um alerta fatal . Isso é tanto um bug do JRE quanto um do Apache.Você pode desativar o envio de registros SNI com a propriedade System jsse.enableSNIExtension = false.
Se você pode alterar o código, é útil usar
SSLCocketFactory#createSocket()
(sem parâmetro de host ou com um soquete conectado). Nesse caso, ele não enviará uma indicação server_name.fonte
System.setProperty ("jsse.enableSNIExtension", "false");
-Djsse.enableSNIExtension=false
. Mas o que mais isso faz? É prejudicial para o resto da segurança do Javas?Também encontramos esse erro em uma nova compilação do servidor Apache.
A correção no nosso caso foi definir um
ServerAlias
nahttpd.conf
que correspondesse ao nome do host ao qual o Java estava tentando se conectar. NossoServerName
foi definido como o nome do host interno. Nosso certificado SSL estava usando o nome do host externo, mas isso não foi suficiente para evitar o aviso.Para ajudar na depuração, você pode usar este comando ssl:
openssl s_client -servername <hostname> -connect <hostname>:443 -state
Se houver um problema com esse nome de host, a mensagem será impressa na parte superior da saída:
SSL3 alert read: warning:unrecognized name
Também devo observar que não recebemos esse erro ao usar esse comando para conectar-se ao nome do host interno, mesmo que não corresponda ao certificado SSL.
fonte
openssl
. É muito útil.SSL3 alert read: warning:unrecognized name
? Eu vejo o alerta impresso, mas a saída não me ajudar a ver, na verdade, essa diferença de nomenclaturaOpenSSL 1.0.1e-fips 11 Feb 2013
,OpenSSL 1.0.2k-fips 26 Jan 2017
eLibreSSL 2.6.5
.Em vez de confiar no mecanismo de host virtual padrão no apache, você pode definir um último host virtual catchall que usa um ServerName arbitrário e um curinga ServerAlias, por exemplo
Dessa forma, você pode usar o SNI e o apache não enviará de volta o aviso SSL.
Obviamente, isso só funciona se você puder descrever todos os seus domínios facilmente usando uma sintaxe curinga.
fonte
*.mydomain.com
sintaxe para ServerAlias. Observe que você pode adicionar vários aliases usandoServerAlias
, por exemploServerAlias *.mydomain.com mydomain.com *.myotherdomain.com
.Deve ser útil. Para tentar novamente um erro SNI no Apache HttpClient 4.4 - a maneira mais fácil de criar (consulte HTTPCLIENT-1522 ):
e
e
fonte
verifyHostname(sslsock, target)
emSSLConnectionSocketFactory.createLayeredSocket
? Como atarget
string é alterada para vazia,verifyHostname
não será bem-sucedida. Estou perdendo algo óbvio aqui?Usar:
fonte
Ocorreu um problema com o boot de primavera e as jvm 1.7 e 1.8. Na AWS, não tivemos a opção de alterar o ServerName e o ServerAlias para corresponder (eles são diferentes); portanto, fizemos o seguinte:
No build.gradle , adicionamos o seguinte:
Isso nos permitiu ignorar o problema com o "Nome não reconhecido".
fonte
Infelizmente, você não pode fornecer propriedades do sistema para a ferramenta jarsigner.exe.
Enviei o defeito 7177232 , referenciando o defeito 7127374 da @eckes e explicando por que o erro foi encerrado.
Meu defeito é especificamente sobre o impacto na ferramenta jarsigner, mas talvez isso os leve a reabrir o outro defeito e resolver o problema adequadamente.
ATUALIZAÇÃO: Na verdade, você PODE fornecer propriedades do sistema à ferramenta Jarsigner, mas não está na mensagem de ajuda. Usar
jarsigner -J-Djsse.enableSNIExtension=false
fonte
Eu bati o mesmo problema e verificou-se que o DNS reverso não estava configurado corretamente, apontou para o nome de host errado para o IP. Depois de corrigir o DNS reverso e reiniciar o httpd, o aviso desapareceu. (se eu não corrigir o DNS reverso, a adição do ServerName também funcionou)
fonte
Meu
VirtualHost
'sServerName
foi comentada por padrão. Funcionou depois de descomentar.fonte
Se você estiver construindo um cliente com Resttemplate, poderá definir apenas o terminal assim: https: // IP / path_to_service e defina requestFactory.
Com esta solução, você não precisa reiniciar o seu TOMCAT ou Apache:
fonte
Também deparei com esse problema ao atualizar do Java 1.6_29 para 1.7.
Surpreendentemente, meu cliente descobriu uma configuração no painel de controle Java que resolve isso.
Na guia Avançado, você pode verificar 'Usar o formato ClientHello compatível com SSL 2.0'.
Isso parece resolver o problema.
Estamos usando miniaplicativos Java em um navegador Internet Explorer.
Espero que isto ajude.
fonte
Eu tive o mesmo problema com um servidor Ubuntu Linux executando o subversion quando acessado via Eclipse.
Ele mostrou que o problema tinha a ver com um aviso quando o Apache (re) iniciou:
Isso ocorreu devido a uma nova entrada
ports.conf
, onde outraNameVirtualHost
diretiva foi inserida juntamente com a diretiva emsites-enabled/000-default
.Após remover a diretiva
ports.conf
, o problema desapareceu (após reiniciar o Apache, naturalmente)fonte
Apenas para adicionar uma solução aqui. Isso pode ajudar os usuários do LAMP
A linha acima mencionada na configuração do host virtual foi a culpada.
Configuração de host virtual quando erro
Configuração de trabalho
fonte
Aqui está a solução para o Appache httpclient 4.5.11. Eu tive um problema com o certificado que tem o curinga sujeito
*.hostname.com
. Ele me retornou a mesma exceção, mas não devo usar a desativação por propriedadeSystem.setProperty("jsse.enableSNIExtension", "false");
porque cometeu um erro no cliente de localização do Google.Encontrei solução simples (apenas modificando o soquete):
fonte
Existe uma maneira mais fácil de você usar o seu próprio HostnameVerifier para confiar implicitamente em determinadas conexões. O problema ocorre no Java 1.7, onde as extensões SNI foram adicionadas e o erro ocorreu devido a uma configuração incorreta do servidor.
Você pode usar "-Djsse.enableSNIExtension = false" para desativar o SNI em toda a JVM ou ler meu blog, onde explico como implementar um verificador personalizado em cima de uma conexão de URL.
fonte