为什么 SSL 握手会出现“无法生成 DH 密钥对”异常?

当我与某些 IRC 服务器建立 SSL 连接时(但不与其他服务器建立 SSL 连接——可能是由于服务器的首选加密方法) ,我会得到以下异常:

Caused by: java.lang.RuntimeException: Could not generate DH keypair
at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:106)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverKeyExchange(ClientHandshaker.java:556)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:183)
at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:893)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1138)
at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1165)
... 3 more

最终原因:

Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:100)
... 10 more

演示这个问题的服务器示例是 aperture.esper.net : 6697(这是一个 IRC 服务器)。服务器的一个例子没有说明问题的 kornbluth.freenode.net : 6697。[毫不奇怪,每个网络上的所有服务器都有相同的行为。]

我的代码(如上所述,在连接到某些 SSL 服务器时可以正常工作)是:

    SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, trustAllCerts, new SecureRandom());
s = (SSLSocket)sslContext.getSocketFactory().createSocket();
s.connect(new InetSocketAddress(host, port), timeout);
s.setSoTimeout(0);
((SSLSocket)s).startHandshake();

正是最后一个 start 握手引发了异常。是的,“ trust AllCerts”有一些神奇的功能; 这些代码强制 SSL 系统不验证证书。(所以... 不是一个确定的问题。)

显然,一种可能性是 esper 的服务器配置错误,但是我搜索并没有找到任何其他关于 esper 的 SSL 端口有问题的人的参考资料,并且‘ openssl’连接到它(见下文)。所以我想知道这是否是 Java 默认 SSL 支持的一个限制,或者别的什么。有什么建议吗?

下面是我使用 commandline 中的“ openssl”连接到 aperture.esper.net 6697时发生的情况:

~ $ openssl s_client -connect aperture.esper.net:6697
CONNECTED(00000003)
depth=0 /C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
verify error:num=18:self signed certificate
verify return:1
depth=0 /C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
verify return:1
---
Certificate chain
0 s:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
i:/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
---
Server certificate
-----BEGIN CERTIFICATE-----
[There was a certificate here, but I deleted it to save space]
-----END CERTIFICATE-----
subject=/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
issuer=/C=GB/ST=England/L=London/O=EsperNet/OU=aperture.esper.net/CN=*.esper.net/emailAddress=support@esper.net
---
No client certificate CA names sent
---
SSL handshake has read 2178 bytes and written 468 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol  : TLSv1
Cipher    : DHE-RSA-AES256-SHA
Session-ID: 51F1D40A1B044700365D3BD1C61ABC745FB0C347A334E1410946DCB5EFE37AFD
Session-ID-ctx:
Master-Key: DF8194F6A60B073E049C87284856B5561476315145B55E35811028C4D97F77696F676DB019BB6E271E9965F289A99083
Key-Arg   : None
Start Time: 1311801833
Timeout   : 300 (sec)
Verify return code: 18 (self signed certificate)
---

如前所述,在所有这些之后,它确实成功地连接了,这比我的 Java 应用程序要好得多。

如果有关系的话,我使用的是 OS X 10.6.8,Java 版本1.6.0 _ 26。

329001 次浏览

问题在于最佳尺寸。Java 接受的最大可接受大小为1024位。这是一个已知的问题(见 JDK-6521495)。

我链接到的 bug 报告提到了使用 BouncyCastle 的 JCE 实现的 解决办法

更新

这被报告为错误 JDK-7044060和最近修复。

但是请注意,该限制仅提高到2048位。对于大于2048位的字节,有 JDK-8072452-删除 DH 密钥的最大质数大小; 修复程序似乎是9。

上面的答案是正确的,但是就变通方法而言,我在将 BouncyCastle 实现设置为首选提供程序时遇到了问题:

java.lang.ArrayIndexOutOfBoundsException: 64
at com.sun.crypto.provider.TlsPrfGenerator.expand(DashoA13*..)

我发现的一个论坛帖子里也讨论了这个问题,但是没有提到解决方案。 Http://www.javakb.com/uwe/forum.aspx/java-programmer/47512/tls-problems

我找到了另一个解决方案,虽然我一点也不满意,但对我的情况很有效。解决方案是将其设置为迪菲-赫尔曼算法根本不可用。然后,假设服务器支持一个替代算法,它将在正常协商过程中进行选择。显然,这样做的缺点是,如果有人设法找到一个服务器,只支持区分-赫尔曼在1024位或更少,这实际上意味着它不会工作在它以前工作的地方。

下面是给定 SSLSocket (在连接之前)可以工作的代码:

List<String> limited = new LinkedList<String>();
for(String suite : ((SSLSocket)s).getEnabledCipherSuites())
{
if(!suite.contains("_DHE_"))
{
limited.add(suite);
}
}
((SSLSocket)s).setEnabledCipherSuites(limited.toArray(
new String[limited.size()]));

真恶心。

尝试从 Java 下载网站下载“ Java 加密扩展(JCE)无限强度管辖权策略文件”并替换 JRE 中的文件。

这对我很有用,我甚至不需要使用 BouncyCastle ——标准的 Sun JCE 能够连接到服务器。

附言。当我在更改策略文件之前尝试使用 BouncyCastle 时,也出现了同样的错误(ArrayIndexOutOfBoundsException: 64) ,所以看起来我们的情况非常相似。

如果您使用的是 jdk1.7.0 _ 04,请升级到 jdk1.7.0 _ 21。

这是我的解决方案(java 1.6) ,也会对我为什么要这样做感兴趣:

我从 javax.security.debug = ssl 中注意到,有时使用的密码套件是 TLS _ DHE _... 有时是 TLS _ ECDHE _... 。如果我加上 BouncyCastle 就会发生后一种情况。如果选择了 TLS _ ECDHE _,大部分时间它都能工作,但并不总是如此,因此即使添加 BouncyCastle 提供程序也是不可靠的(每隔一段时间左右都会出现同样的错误)。我猜测在 Sun SSL 实现的某个地方,有时它选择 DHE,有时它选择 ECDHE

所以这里提供的解决方案完全依赖于删除 TLS _ DHE _ 加密。

因此,通过以下方法创建服务器认证文件:

echo |openssl s_client -connect example.org:443 2>&1 |sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'

保存它,因为稍后将引用它,这里是 SSL http get 的解决方案,不包括 TLS _ DHE _ cipher 套件。

package org.example.security;


import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.Socket;
import java.net.URL;
import java.net.UnknownHostException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;


import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;


import org.apache.log4j.Logger;


public class SSLExcludeCipherConnectionHelper {


private Logger logger = Logger.getLogger(SSLExcludeCipherConnectionHelper.class);


private String[] exludedCipherSuites = {"_DHE_","_DH_"};


private String trustCert = null;


private TrustManagerFactory tmf;


public void setExludedCipherSuites(String[] exludedCipherSuites) {
this.exludedCipherSuites = exludedCipherSuites;
}


public SSLExcludeCipherConnectionHelper(String trustCert) {
super();
this.trustCert = trustCert;
//Security.addProvider(new BouncyCastleProvider());
try {
this.initTrustManager();
} catch (Exception ex) {
ex.printStackTrace();
}
}


private void initTrustManager() throws Exception {
CertificateFactory cf = CertificateFactory.getInstance("X.509");
InputStream caInput = new BufferedInputStream(new FileInputStream(trustCert));
Certificate ca = null;
try {
ca = cf.generateCertificate(caInput);
logger.debug("ca=" + ((X509Certificate) ca).getSubjectDN());
} finally {
caInput.close();
}


// Create a KeyStore containing our trusted CAs
KeyStore keyStore = KeyStore.getInstance("jks");
keyStore.load(null, null);
keyStore.setCertificateEntry("ca", ca);


// Create a TrustManager that trusts the CAs in our KeyStore
String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
tmf.init(keyStore);
}


public String get(URL url) throws Exception {
// Create an SSLContext that uses our TrustManager
SSLContext context = SSLContext.getInstance("TLS");
context.init(null, tmf.getTrustManagers(), null);
SSLParameters params = context.getSupportedSSLParameters();
List<String> enabledCiphers = new ArrayList<String>();
for (String cipher : params.getCipherSuites()) {
boolean exclude = false;
if (exludedCipherSuites != null) {
for (int i=0; i<exludedCipherSuites.length && !exclude; i++) {
exclude = cipher.indexOf(exludedCipherSuites[i]) >= 0;
}
}
if (!exclude) {
enabledCiphers.add(cipher);
}
}
String[] cArray = new String[enabledCiphers.size()];
enabledCiphers.toArray(cArray);


// Tell the URLConnection to use a SocketFactory from our SSLContext
HttpsURLConnection urlConnection =
(HttpsURLConnection)url.openConnection();
SSLSocketFactory sf = context.getSocketFactory();
sf = new DOSSLSocketFactory(sf, cArray);
urlConnection.setSSLSocketFactory(sf);
BufferedReader in = new BufferedReader(new InputStreamReader(urlConnection.getInputStream()));
String inputLine;
StringBuffer buffer = new StringBuffer();
while ((inputLine = in.readLine()) != null)
buffer.append(inputLine);
in.close();


return buffer.toString();
}


private class DOSSLSocketFactory extends javax.net.ssl.SSLSocketFactory {


private SSLSocketFactory sf = null;
private String[] enabledCiphers = null;


private DOSSLSocketFactory(SSLSocketFactory sf, String[] enabledCiphers) {
super();
this.sf = sf;
this.enabledCiphers = enabledCiphers;
}


private Socket getSocketWithEnabledCiphers(Socket socket) {
if (enabledCiphers != null && socket != null && socket instanceof SSLSocket)
((SSLSocket)socket).setEnabledCipherSuites(enabledCiphers);


return socket;
}


@Override
public Socket createSocket(Socket s, String host, int port,
boolean autoClose) throws IOException {
return getSocketWithEnabledCiphers(sf.createSocket(s, host, port, autoClose));
}


@Override
public String[] getDefaultCipherSuites() {
return sf.getDefaultCipherSuites();
}


@Override
public String[] getSupportedCipherSuites() {
if (enabledCiphers == null)
return sf.getSupportedCipherSuites();
else
return enabledCiphers;
}


@Override
public Socket createSocket(String host, int port) throws IOException,
UnknownHostException {
return getSocketWithEnabledCiphers(sf.createSocket(host, port));
}


@Override
public Socket createSocket(InetAddress address, int port)
throws IOException {
return getSocketWithEnabledCiphers(sf.createSocket(address, port));
}


@Override
public Socket createSocket(String host, int port, InetAddress localAddress,
int localPort) throws IOException, UnknownHostException {
return getSocketWithEnabledCiphers(sf.createSocket(host, port, localAddress, localPort));
}


@Override
public Socket createSocket(InetAddress address, int port,
InetAddress localaddress, int localport) throws IOException {
return getSocketWithEnabledCiphers(sf.createSocket(address, port, localaddress, localport));
}


}
}

最后是如何使用它(certFilePath,如果证书的路径保存自 openssl) :

try {
URL url = new URL("https://www.example.org?q=somedata");
SSLExcludeCipherConnectionHelper sslExclHelper = new SSLExcludeCipherConnectionHelper(certFilePath);
logger.debug(
sslExclHelper.get(url)
);
} catch (Exception ex) {
ex.printStackTrace();
}

这是一篇相当老的文章,但是如果使用 ApacheHTTPD,则可以限制 DH 的大小。 请参阅 href = “ http://httpd.apache.org/docs/current/ssl/ssl _ faq.html # javadh”> http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

“ Java 加密扩展(JCE)无限强度管辖权策略文件”的答案对我不起作用,但是 BouncyCastle 的 JCE 提供者建议起作用了。

以下是我在 Mac OSC 10.7.5上使用 Java 1.6.0 _ 65-b14-462所采取的步骤

1)下载这些罐子:

2)将这些 jar 移动到 $JAVA _ HOME/lib/ext

3)编辑 $JAVA _ HOME/lib/security/JAVA.security 如下: Provider. 1 = org.ouncycastle.jce.Provider. BouncyCastleProvider

使用 JRE 重新启动应用程序并尝试一下

可以动态安装提供程序:

1)下载这些罐子:

  • bcprov-jdk15on-152.jar
  • bcprov-ext-jdk15on-152.jar

2)将 jar 复制到 WEB-INF/lib(或类路径)

3)动态添加提供者:

import org.bouncycastle.jce.provider.BouncyCastleProvider;

...

Security.addProvider(new BouncyCastleProvider());

如果服务器支持不包含 DH 的密码,则可以强制客户端选择该密码并避免 DH 错误。例如:

String pickedCipher[] ={"TLS_RSA_WITH_AES_256_CBC_SHA"};
sslsocket.setEnabledCipherSuites(pickedCipher);

请记住,指定精确的密码从长远来看很容易中断。

您可以在 jdk 中完全禁用 DHE,编辑 jre/lib/security/java.security 并确保禁用 DHE,例如

jdk.tls.disabledAlgorithms=SSLv3, DHE.

如果您仍然被这个问题 还有所困扰,那么您正在使用 Apache httpd v > 2.4.7,请尝试这样做: http://httpd.apache.org/docs/current/ssl/ssl_faq.html#javadh

复制自 url :

从2.4.7版开始,mod _ ssl 将使用 DH 参数,其中包括长度超过1024位的素数。然而,Java7和更早的版本将对 DH 质数大小的支持限制在最大1024位。

如果基于 Java 的客户端中止,例如 java.lang。未能生成 DH 密钥对和 java.security。例外: 质数大小必须是64的倍数,并且只能在512到1024之间(包括) ,httpd 记录 tlsv1警报内部错误(SSL 警报号80)(在 LogLevel 信息或更高) ,您可以使用 SSLCipherSuite (可能与 SSLHonorCipherOrder 结合使用)重新排列 mod _ SSL 的密码列表,或者您可以使用具有1024位质数的自定义 DH 参数,该参数总是优先于任何内置 DH 参数。

若要生成自定义 DH 参数,请使用

开启 dhparam 1024

或者,您可以使用 RFC 2409第6.2节中的下列标准1024位 DH 参数:

-----BEGIN DH PARAMETERS-----
MIGHAoGBAP//////////yQ/aoiFowjTExmKLgNwc0SkCTgiKZ8x0Agu+pjsTmyJR
Sgh5jjQE3e+VGbPNOkMbMCsKbfJfFDdP4TVtbVHCReSFtXZiXn7G9ExC6aY37WsL
/1y29Aa37e44a/taiZ+lrp8kEXxLH+ZJKGZR7OZTgf//////////AgEC
-----END DH PARAMETERS-----

将包括“ BEGIN DH PARAMETERS”和“ END DH PARAMETERS”行的自定义参数添加到您使用 SSL證 icateFile 指令配置的第一个证书文件的末尾。


我在客户端使用 java 1.6,它解决了我的问题。我没有降低密码套件或喜欢,但添加了一个自定义生成的 DH 参数到证书文件。.

我在 Yandex Maps 服务器、 JDK 1.6和 Apache HttpClient 4.2.1上遇到了同样的问题

javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated

通过 -Djavax.net.debug=all启用调试后,日志中有一条消息

Could not generate DH keypair

我通过添加 BouncyCastle 库 bcprov-jdk16-1.46.jar并在地图服务类中注册一个提供者来解决这个问题

public class MapService {


static {
Security.addProvider(new BouncyCastleProvider());
}


public GeocodeResult geocode() {


}


}

在第一次使用 MapService时注册提供程序。

我们得到了同样的异常错误返回,修复它很容易下班后上网冲浪。

我们下载了 oracle.com 上能找到的最高版本的 jdk,安装了它,并将 Jboss 应用服务器指向安装的新 jdk 的目录。

重新启动 Jboss,重新处理,问题解决! ! !

通过升级到 JDK 8解决了这个问题。

对我来说,下面的命令行解决了这个问题:

Java-jar-Dhttps.protocol = TLSv1.2-Dloyment.security.TLSv1.2 = true - Djavax.net.debug = ssl: handshake XXXXX.jar

我使用的是 JDK 1.7.0 _ 79

我在竹子5.7 + Gradle 项目 + Apache 中得到了这个错误。Gradle 试图通过 SSL 从我们的一个服务器获取一些依赖项。

解决方案:

  1. Generate DH Param:

使用 OpenSSL:

openssl dhparam 1024

示例输出:

-----BEGIN DH PARAMETERS-----
MIGHfoGBALxpfMrDpImEuPlhopxYX4L2CFqQov+FomjKyHJrzj/EkTP0T3oAkjnS
oCGh6p07kwSLS8WCtYJn1GzItiZ05LoAzPs7T3ST2dWrEYFg/dldt+arifj6oWo+
vctDyDqIjlevUE+vyR9MF6B+Rfm4Zs8VGkxmsgXuz0gp/9lmftY7AgEC
-----END DH PARAMETERS-----
  1. 将输出附加到证书文件(用于 Apache-SSLCertificateFile参数)

  2. 重启阿帕奇

  3. 重启竹子

  4. 尝试再次构建项目

我在 JDK 1.6.45上使用 coldFusion 8,遇到了 < cfdocument... > 只给我红叉而不是图像的问题,而且 cfhttp 无法用 ssl 连接到本地 Web 服务器。

我用冷融合8重现的测试脚本是

<CFHTTP URL="https://www.onlineumfragen.com" METHOD="get" ></CFHTTP>
<CFDUMP VAR="#CFHTTP#">

这给了我相当普遍的错误“ I/O 异常: 对等未经身份验证。” 然后,我尝试将服务器的证书(包括根证书和中间证书)添加到 java 密钥存储库以及 coldFusion 密钥存储库,但是没有任何帮助。 然后我用

java SSLPoke www.onlineumfragen.com 443

然后

javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair

还有

Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be
multiple of 64, and can only range from 512 to 1024 (inclusive)
at com.sun.crypto.provider.DHKeyPairGenerator.initialize(DashoA13*..)
at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:627)
at com.sun.net.ssl.internal.ssl.DHCrypt.<init>(DHCrypt.java:107)
... 10 more

然后我有了这样一个想法: webserver (在我的例子中是 apache)有非常现代的 ssl 密码,并且非常有限制性(qualys 得分为 a +) ,并且使用了超过1024位的强敌菲-赫尔曼组。显然,ColdFusion 和 JavaJDK 1.6.45无法处理这个问题。 在漫长的旅程中,下一步是考虑为 Java 安装一个替代安全提供商,于是我决定使用弹力城堡。 另见 href = “ http://www.itcsolutions.eu/2011/08/22/how-to-use-ouncy-castle-crypgraphy-api-in-netbeans-or-eclipse-for-java-jse-Projects/”rel = “ nofollow norefrer”> http://www.itcsolutions.eu/2011/08/22/how-to-use-bouncy-castle-cryptographic-api-in-netbeans-or-eclipse-for-java-jse-projects/

然后我下载了

bcprov-ext-jdk15on-156.jar

http://www.bouncycastle.org/latest_releases.html安装到 C: jdk6 _ 45 jre lib ext 或者不管你的 jdk 在哪里,在 coldFusion 8的原始安装中,它应该在 C: JRun4 jre lib ext 下,但是我使用了一个位于 coldFusion 目录之外的更新的 jdk (1.6.45)。将 bcprov-ext-jdk15on-156.jar 放在 ext 目录中非常重要(这花费了我大约两个小时和一些头发; -) 然后我编辑了文件 C: jdk6 _ 45 jre lib security java.security (使用 wordpad 而不是 edit. exe!)并为新的提供者放入一行。后来名单看起来像

#
# List of providers and their preference orders (see above):
#
security.provider.1=org.bouncycastle.jce.provider.BouncyCastleProvider
security.provider.2=sun.security.provider.Sun
security.provider.3=sun.security.rsa.SunRsaSign
security.provider.4=com.sun.net.ssl.internal.ssl.Provider
security.provider.5=com.sun.crypto.provider.SunJCE
security.provider.6=sun.security.jgss.SunProvider
security.provider.7=com.sun.security.sasl.Provider
security.provider.8=org.jcp.xml.dsig.internal.dom.XMLDSigRI
security.provider.9=sun.security.smartcardio.SunPCSC
security.provider.10=sun.security.mscapi.SunMSCAPI

(见位置1的新版本)

然后完全重新启动冷聚变服务。 你可以的

java SSLPoke www.onlineumfragen.com 443 (or of course your url!)

享受这种感觉。 当然 < cfhttp 和 < cfdocument 的工作就像一个魅力和喜欢之前,我们“硬化”我们的 ssl 密码在阿帕奇!

多么美好的一夜,多么美好的一天。希望这将有助于(部分或全部)在那里的人。如果你有问题,只是邮件我在信息... (域名以上)。

我曾经在使用 IBM JDK 访问 java SVN 客户端的 SVN.apache.org 时遇到过类似的错误。目前,svn.apache.org 使用客户端的密码首选项。

仅仅运行了一次数据包捕获/javax.net.debug = ALL 之后,我就能够将一个 DHE 密码列入黑名单,这对我来说很有用(ECDHE 是协商的)。

.../java/jre/lib/security/java.security:
jdk.tls.disabledAlgorithms=SSL_DHE_RSA_WITH_AES_256_CBC_SHA

当不容易更改客户端时,这是一个很好的快速修复方法。

我在运行 JDK6的 CentOS 服务器上遇到了 SSL 错误。

我的计划是安装一个更高版本的 JDK (JDK7) ,以便与 JDK6共存,但结果是,仅仅使用 rpm -i安装更新的 JDK 是不够的。

JDK7安装只有使用如下所示的 rpm -U升级选项才能成功。

1. 下载 JDK 7

wget -O /root/jdk-7u79-linux-x64.rpm --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; o raclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/7u79-b15/jdk-7u79-linux-x64.rpm"

2. RPM 安装失败

rpm -ivh jdk-7u79-linux-x64.rpm
Preparing...                ########################################### [100%]
file /etc/init.d/jexec from install of jdk-2000:1.7.0_79-fcs.x86_64 conflicts with file from package jdk-2000:1.6.0_43-fcs.x86_64

3. RPM 升级成功

rpm -Uvh jdk-7u79-linux-x64.rpm
Preparing...                ########################################### [100%]
1:jdk                    ########################################### [100%]
Unpacking JAR files...
rt.jar...
jsse.jar...
charsets.jar...
tools.jar...
localedata.jar...
jfxrt.jar...

4. 确认新版本

java -version
java version "1.7.0_79"
Java(TM) SE Runtime Environment (build 1.7.0_79-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.79-b02, mixed mode)

您可能有不正确的 Maven 依赖项。 您必须在 Maven 依赖层次结构中找到这些库:

bcprov-jdk14, bcpkix-jdk14, bcmail-jdk14

如果您有这些依赖项,那么就是错误,您应该这样做:

添加依赖项:

<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcmail-jdk15on</artifactId>
<version>1.59</version>
</dependency>

从包含错误依赖项的工件中排除这些依赖项,在我的例子中是:

<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
<exclusions>
<exclusion>
<groupId>org.bouncycastle</groupId>
<artifactId>bctsp-jdk14</artifactId>
</exclusion>
<exclusion>
<groupId>bouncycastle</groupId>
<artifactId>bcprov-jdk14</artifactId>
</exclusion>
<exclusion>
<groupId>bouncycastle</groupId>
<artifactId>bcmail-jdk14</artifactId>
</exclusion>
</exclusions>
</dependency>

最近我有同样的问题和升级后的 jdk 版本从 1.6.0 _ 45Jdk1.7.0 _ 191解决了这个问题。

Window-> Preferences-> Java-> Installated JRE-> select the jre And Edit. And in the Default VM Arguments enter

- Dcom.sun.net.ssl.ableleECC = false

单击 Finish