服务器的瞬时 Diffie-Hellman 公共密钥过弱
最近了解了一下证书的构成、DER编码结构、SSL协议的握手过程,尝试代码写了一个动态生成证书的EchoServer。
不过在IE浏览器下把证书加到信任列表的话可以正常访问,
但在Chrome下报:服务器的瞬时 Diffie-Hellman 公共密钥过弱,无法访问。
网上搜了一下相关解释,都没有能从SSL的握手协议来做个解释,尝试从代码中去掉了几个CipherSuite
好像也没效果。。
请教一下。
示例代码:
不过在IE浏览器下把证书加到信任列表的话可以正常访问,
但在Chrome下报:服务器的瞬时 Diffie-Hellman 公共密钥过弱,无法访问。
网上搜了一下相关解释,都没有能从SSL的握手协议来做个解释,尝试从代码中去掉了几个CipherSuite
好像也没效果。。
请教一下。
示例代码:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.54</version>
</dependency>
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.security.KeyStore;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.SSLServerSocketFactory;
import javax.net.ssl.TrustManagerFactory;
public class SSLServerDemo implements Runnable {
private Socket socket;
private SSLServerDemo(Socket socket) {
this.socket = socket;
}
public static void main(String[] args) throws Exception {
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SUNX509"/*NEWSUNX509*/);
KeyStore serverStore = CertMakeDemo.createKeyStore("DemoServer", "123456");
kmf.init(serverStore, "123456".toCharArray());
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SUNX509"/*PKIX*/);
KeyStore clientStore = KeyStore.getInstance("PKCS12"/*JKS, WINDOWS-ROOT, JCEKS等*/);
clientStore.load(null, null);
tmf.init(clientStore);
SSLContext context = SSLContext.getInstance("SSL"/*TLS, SSLV3, DEFAULT, "TLSV1"*/);
context.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
SSLParameters parameters = context.getDefaultSSLParameters();
List<String> cipherSuites = new ArrayList<String>(Arrays.asList(parameters.getCipherSuites()));
cipherSuites.remove("TLS_DHE_RSA_WITH_AES_128_CBC_SHA");
parameters.setCipherSuites(cipherSuites.toArray(new String[0]));
System.out.println(Arrays.asList(parameters.getCipherSuites()));
SSLServerSocketFactory factory = context.getServerSocketFactory();
SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(443);
//serverSocket.setNeedClientAuth(true);浏览器会提示选择个人私钥证书,tmf需要能够认证客户端证书
System.out.println("server started. try https://localhost");
ExecutorService executor = Executors.newCachedThreadPool();
for (Socket socket; (socket = serverSocket.accept()) != null;) {
executor.submit(new SSLServerDemo(socket));
}
}
public void run() {
BufferedReader in = null;
BufferedWriter out = null;
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF-8"));
out.write("HTTP/1.1 200 OK\r\n");
out.write("Content-Type: text/html;charset=UTF-8\r\n");
out.write("\r\n");
for (String line; (line = in.readLine()) != null;) {
out.write(line + "<br>\r\n");
out.flush();
System.out.println(line);
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (!socket.isClosed() && socket.isConnected()) {
closeQuietly(in);
closeQuietly(out);
}
}
}
private void closeQuietly(Closeable closeable) {
if (closeable != null) {
try {
closeable.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.DEROctetString;
import org.bouncycastle.asn1.DERSequence;
import org.bouncycastle.asn1.DERTaggedObject;
import org.bouncycastle.asn1.x500.X500Name;
import org.bouncycastle.asn1.x509.Extension;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.cert.X509v3CertificateBuilder;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
public class CertMakeDemo {
public static void main(String[] args) throws Exception {
X500Name subject = new X500Name("CN=root, O=root, OU=root");
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(1024);
KeyPair pair = gen.generateKeyPair();
X509Certificate certificate = signerSelf(subject, pair);
System.out.println("证书:" + certificate);
KeyStore pkcs12 = KeyStore.getInstance("PKCS12");
pkcs12.load(null, null);
pkcs12.setKeyEntry("root", pair.getPrivate(), "123456".toCharArray(), new Certificate[] { certificate });
for (Enumeration<String> e = pkcs12.aliases(); e.hasMoreElements();) {
String alias = e.nextElement();
System.out.println(pkcs12.getCertificateChain(alias));
System.out.println(pkcs12.getKey(alias, "123456".toCharArray()));
}
OutputStream out = new FileOutputStream("f:/temp/root.pfx");
pkcs12.store(out, "123456".toCharArray());
out.close();
//root为张三签发证书
X500Name zsSubject = new X500Name("CN=张三, O=张三, OU=张三");
gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(1024);
KeyPair zsKeypair = gen.generateKeyPair();
X509Certificate zsCertificate = signer(zsSubject, zsKeypair.getPublic(), certificate, pair.getPrivate());
System.out.println("张三证书:" + zsCertificate);
out = new FileOutputStream("f:/temp/zhangsan.cer");
out.write(zsCertificate.getEncoded());
out.close();
}
public static KeyStore createKeyStore(String subjectName, String pwd) throws Exception {
X500Name subject = new X500Name("CN=" + subjectName);
KeyPairGenerator gen = KeyPairGenerator.getInstance("RSA");
gen.initialize(1024);
KeyPair pair = gen.generateKeyPair();
X509Certificate certificate = signerSelf(subject, pair);
KeyStore store = KeyStore.getInstance("PKCS12");
store.load(null, null);
store.setKeyEntry("root", pair.getPrivate(), pwd.toCharArray(), new Certificate[] { certificate });
return store;
}
public static X509Certificate signer(X500Name subject, PublicKey subjectPublicKey,//
X509Certificate issuerCert, PrivateKey issuerPrivateKey) throws Exception {
X500Name issuer = X500Name.getInstance(issuerCert.getSubjectX500Principal().getEncoded());
String signatureAlgorithm = issuerCert.getSigAlgName();
return signer(subject, subjectPublicKey, issuer, issuerPrivateKey, signatureAlgorithm);
}
public static X509Certificate signerSelf(X500Name subject, KeyPair pair) throws Exception {
String signatureAlgorithm = "SHA1With" + pair.getPrivate().getAlgorithm();
return signer(subject, pair.getPublic(), subject, pair.getPrivate(), signatureAlgorithm);
}
public static X509Certificate signer(X500Name subject, PublicKey subjectPublicKey,//
X500Name issuer, PrivateKey issuerPrivateKey, String signatureAlgorithm) throws Exception {
BigInteger sn = new BigInteger(new SimpleDateFormat("yyyyMMdd").format(new Date()));
Date notBefore = new Date();
Date notAfter = new Date(notBefore.getTime() + 365L * 24 * 60 * 60 * 1000);
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfo.getInstance(subjectPublicKey.getEncoded());
ContentSigner signer = new JcaContentSignerBuilder(signatureAlgorithm).build(issuerPrivateKey);
X509v3CertificateBuilder builder = new X509v3CertificateBuilder(//
issuer, sn, notBefore, notAfter, subject, publicKeyInfo);
builder.addExtension(createSubjectAlternativeName());
byte[] certBytes = builder.build(signer).getEncoded();
X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X509")//
.generateCertificate(new ByteArrayInputStream(certBytes));
return certificate;
}
/** 使用者备用名称:绑定证书和域名,解决此证书与网站不符的问题 */
private static Extension createSubjectAlternativeName() throws Exception {
DERTaggedObject tag1 = new DERTaggedObject(false, 2, new DEROctetString("localhost".getBytes()));
DERTaggedObject tag2 = new DERTaggedObject(false, 2, new DEROctetString("127.0.0.1".getBytes()));
DERSequence seq = new DERSequence(new ASN1Encodable[] { tag1, tag2 });
Extension extension = new Extension(Extension.subjectAlternativeName, false, new DEROctetString(seq));
return extension;
}
}
...全文
相关推荐
SSLTLS 服务器瞬时 Diffie-Hellman 公共密钥过弱【原理扫描】 .txt
该文件关注的是SSL/TLS服务器配置中的一个安全问题,即瞬时Diffie-Hellman公共密钥过弱。这个问题可能导致加密通信的强度不足,使得服务器容易受到中间人攻击。解决方法通常涉及加强SSL/
SSLTLS 服务器瞬时 Diffie-Hellman 公共密钥弱
代码下载地址: https://pan.quark.cn/s/9b9d08a9c5d5 【修补缺陷-验证有效】SSLTLS 服务器瞬间 Diffie-Hellman 公共密钥强度不足
解决jetty环境ssl的瞬时 Diffie-Hellman 公共密钥过弱
解决jetty8、jdk1.6环境下的ssl问题,示服务器的瞬时 Diffie-Hellman 公共密钥过弱,可以通过设置如下参数解决
SSL/TLS漏洞与修复[源码]
本文深入分析了SSL/TLS密码套件中常见的漏洞种类及其原因,包括SSL/TLS协议信息泄露漏洞、服务器瞬时Diffie-Hellman公共密钥过弱漏洞以及OpenSSL拒绝服务漏洞。针对这些漏洞,文
具有防泄漏功能的有损活板门功能和公共密钥加密
- **实现**:基于决策Diffie-Hellman(Decisional Diffie-Hellman, DDH)假设,lrLTF能够在一定泄漏率下保持安全性。


