前面简单的学习了证书的一些概念。继续学习证书的相关知识及其应用。
提到证书的应用,可以在输入的地址栏看到https,亦http+SSL/TLS。https在http上多了一个安全性。
当我们创建好证书,并且在服务器端配置好后,输入https的URL,此时浏览器会为我们完成SSL/TLS握手协议。
SSL/TLS握手协议分为3次,亦三次握手。
第一次:客户端浏览器会产生随机数RNC,然后发送SSL信息,算法信息,随机数RNC给服务端。服务端也产生随机数RNC,然后发送SSL信息,算法信息,随机数RNS给客户端,服务端证书,客户端证书请求(可有)。 --算法协商
第二次:客户端验证证书。若有客户端证书请求,客户端会发送证书给服务器,服务器验证。 --身份验证
第三次:客户端产生随机数PMS,使用服务端公钥加密随机数PMS,发送随机数PMS加密信息。服务端用私钥解密,获得PMS。然后双方使用随机数RNC,RNS,和PMS建立主密钥MS。主密钥是对称密钥。主密钥生成后,双方会用主密钥构建会话,通知终止握手。 --确定密钥
握手完后,就使用主密钥加密,解密信息进行通信了,证书在这里的作用就是确认你访问的地址可靠性。可以在这篇文章更加了解握手的内容http://www.infoq.com/cn/articles/HTTPS-Connection-Jeff-Moser。
开始总有一个疑问,既然公钥,私钥可以加密解密,为什么还要弄一个对称密钥出来做加密,解密。查下资料,人家说非对称密钥加密,解密效率低,对称密钥效率高一些,具体怎么高就要去把数学学好了,呵呵,就这样知道就有了。
接下来看一下代码是如何实现。我们的代码是运行在容器当中,连接主要靠容器做的,默认情况下都是http开头。若要https开头,就要在容器里面配置一下。我就讲下tomcat的配置。
tomcat负责连接的是connector,到tomcat的conf目录下打开server.xml文件,找到connector这一块,配置https:
<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol" SSLEnabled="true" maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" keystoreFile="conf/liu.keystore" keystorePass="123456"/>
https默认端口443,keystorefile指定了密钥库,clientAuth指客户端证书请求,默认false。
配置完后,你的地址就是使用https开头,并且访问该地址就要通过SSL/TSL协议了。
问题:我开始配置的时候,属性protocol="HTTP/1.1",这是会报错,说tomcat not find a matching property。我上面配置NIO,当然也可以配置成BIO。
浏览器帮我们做了SSL/TLS的功能,客户端用程序访问服务器,是如何做的呢?
那就要用到HttpsURLConnection和SSLSocketFactory这二个类了。
HttpsURLConnection用于建立连接,SSLSocketFactory做验证。
URL url = new URL("httpsUrl");
HttpsURLConnection httpsConn = (HttpsURLConnection) url
.openConnection();
SSLClientSocket client = new SSLClientSocket();
SSLSocketFactory sslSocketFactory = client.getFactoryNoPath();
httpsConn.setSSLSocketFactory(sslSocketFactory);
httpsConn.getInputStream();
public SSLSocketFactory getFactoryNoPath(){
SSLContext context = null;
try {
X509TrustManager tm = new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] xcs, String string) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] xcs, String string) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
context = SSLContext.getInstance("SSL");
context.init(null, new TrustManager[] {tm}, null);
} catch (KeyManagementException ex) {
Logger.getLogger(SSLClientSocket.class.getName()).log(Level.SEVERE, null, ex);
}catch (NoSuchAlgorithmException ex) {
Logger.getLogger(SSLClientSocket.class.getName()).log(Level.SEVERE, null, ex);
}
SSLSocketFactory ssf = context.getSocketFactory();
return ssf;
}
步骤很简单,通过URL获得HttpsURLConnection,然后设置一下SSLSocketFactory。SSLClientSocket是自己以前写的,用于获取SSLSocketFactory,这一个socketFactory的并没有做验证服务器证书操作。
开始的时候一直一个错误的理解,认为客户端这边已经得到服务器端证书,而且要验证的话必须给服务端证书,而且写在getAcceptedIssuers里。
在客户端,在checkServerTrusted里面,做服务端证书验证。在服务端,在checkClientTrusted里面做客户端证书验证。
在看一下服务器和客户端都使用程序通信,怎么实现SSL通信
客户端
public void clientSocket(String path) {
SSLContext context = null;
try {
KeyTool keytool = new KeyTool();
KeyStore keyStore = keytool.getKeyStore(path);
X509Certificate[] x509 = new X509Certificate[]{(X509Certificate)keytool.getCertificate(keyStore, "serverkey")};
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(keyStore);
TrustManager[] tm = tmf.getTrustManagers();
context = SSLContext.getInstance("SSL");
context.init(null, new TrustManager[]{new SSLTrustManager(x509)}, null);
//context.init(null,tm, null);
} catch (KeyManagementException ex) {
Logger.getLogger(SSLClientSocket.class.getName()).log(Level.SEVERE, null, ex);
} catch (KeyStoreException ex) {
Logger.getLogger(SSLClientSocket.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(SSLClientSocket.class.getName()).log(Level.SEVERE, null, ex);
}
SSLSocketFactory ssf = context.getSocketFactory();
try {
SSLSocket ss = (SSLSocket) ssf.createSocket("localhost", 8000);
System.out.println("customer already");
ObjectInputStream os = new ObjectInputStream(ss.getInputStream());
System.out.println(os.readObject());
os.close();
ss.close();
System.out.println("ok");
} catch (ClassNotFoundException ex) {
Logger.getLogger(SSLClientSocket.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(SSLClientSocket.class.getName()).log(Level.SEVERE, null, ex);
}
}
可以根据该方法获取服务器证书
Certificate[] aCerts = ss.getSession().getPeerCertificates();
服务端
public void sslServerSocket(String path) {
boolean flag = true;
SSLContext context = null;
try {
KeyTool keytool = new KeyTool();
KeyStore keyStore = keytool.getKeyStore(path);
PrivateKey pk = keytool.getPrivateKey(keyStore, "serverkey");
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(keyStore, "123456".toCharArray());
X509Certificate[] x509 = new X509Certificate[]{(X509Certificate)keytool.getCertificate(keyStore, "serverkey")};
KeyManager[] km = kmf.getKeyManagers();
// TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
// tmf.init(keyStore);
// TrustManager[] tm = tmf.getTrustManagers();
context = SSLContext.getInstance("SSL");
context.init(new KeyManager[]{new SSLKeyManager(pk,x509)}, null, null);
//context.init(km, null, null);
} catch (KeyManagementException ex) {
Logger.getLogger(SSLServerSockets.class.getName()).log(Level.SEVERE, null, ex);
} catch (KeyStoreException ex) {
Logger.getLogger(SSLServerSockets.class.getName()).log(Level.SEVERE, null, ex);
} catch (UnrecoverableKeyException ex) {
Logger.getLogger(SSLServerSockets.class.getName()).log(Level.SEVERE, null, ex);
} catch (NoSuchAlgorithmException ex) {
Logger.getLogger(SSLServerSockets.class.getName()).log(Level.SEVERE, null, ex);
}
SSLServerSocketFactory ssf = context.getServerSocketFactory();
try {
SSLServerSocket ss = (SSLServerSocket) ssf.createServerSocket(8000);
System.out.println("wait for customer connect");
while (flag) {
Socket s = ss.accept();
System.out.println("accept customer connecting");
ObjectOutputStream os = new ObjectOutputStream(s.getOutputStream());
os.writeObject("echo: hello");
os.flush();
os.close();
System.out.println();
s.close();
}
ss.close();
} catch (IOException ex) {
Logger.getLogger(SSLServerSockets.class.getName()).log(Level.SEVERE, null, ex);
}
}
我代码里面初始化KeyManager/TrustManager用了二种方式,一种是从factory里面创建,另一种是直接构建他们的实现类。keystore我初学的时候已经写了怎么获得,keytool是自己写的类。
分享到:
相关推荐
"Certificate scrum"可能是指获得Scrum认证的过程,这通常包括学习Scrum的基本原则、角色、事件和工件,并通过相关的认证考试。 在Scrum中,有三个核心角色:产品负责人(Product Owner)、Scrum Master和开发团队...
《全面掌握Java2认证》是一份综合性的学习资源,旨在帮助学员系统地学习并准备SCJP(Sun Certified Programmer for the Java 2 Platform)考试。SCJP是Java开发人员的基础认证,证明了持有者具备编写合格Java程序的...
**进一步学习资源:** - **Reading Date and Time Values**:介绍了如何使用SAS中的Informat来读取日期和时间数据。 - **Reading Free-Format Data**:讲解了如何使用SAS读取自由格式的数据,包括如何使用PAD、...
通过这个SUN Java证书教程,开发者不仅可以学习到Java证书的基础知识,还能深入理解如何在实际项目中应用这些概念,以确保应用的安全性。对于从事Java开发或者对网络安全感兴趣的人员来说,这是一个非常有价值的资源...
AWS Solution Architect Certificate是亚马逊网络服务(Amazon Web Services, AWS)提供的一个重要认证,旨在验证个人在设计和实施基于AWS云的解决方案方面的能力。这个证书对于那些希望成为AWS解决方案架构师的专业...
《Complete Java2 Certificate》是针对Sun Certified Java Programmer (SCJP)认证的一份详细学习资源,旨在帮助考生掌握Java编程的基础知识并顺利通过考试。SCJP是Java程序员的入门级认证,证明了持有者具备编写合格...
tensorflow certificate 开发者认证 深度学习证书 Google认证 5道建模问题 文本分类图像分类时序预测 参考 本人已获得认证 模型搭建 保存为h5格式 keras numpy pandas 自然语言处理 祝你100美元花得值!该证书旨在让...
压缩包中的唯一文件名"certificate"可能包含的是证书的详细信息,如考试指南、学习资料、样题集、申请表格、证书样本等。这些文档通常会帮助考生了解认证的要求、考试结构、准备策略,以及完成认证后获得的权益。...
SAS软件和临床试验标准不断更新,考生需要保持持续学习,关注SAS新版本的功能改进和临床试验的新要求,以保持专业竞争力。 综上所述,SAS临床试验认证题库是一个全面覆盖SAS在临床试验中应用的知识体系,对考生的...
算法证书_algorithm_certificate1 概述: 本资源是关于算法设计和分析的在线课程的证书,提供了算法设计和分析的主要topics,包括渐进分析、分治算法、排序和搜索、基本随机算法、图搜索、最短路径、堆、搜索树和...
通过学习和分析这些源码,开发者可以更深入地理解Java安全框架的工作原理,并能应用于实际的加密和认证场景。 为了确保代码的安全性和正确性,开发者需要熟悉相关的安全最佳实践,比如定期更新密钥和证书,防止中间...
标题“ITIL_Foundation_Certificate_Syllabus”直指ITIL(Information Technology Infrastructure Library)基础证书课程的大纲,这标志着该文档旨在为IT服务管理领域的初学者提供全面而深入的学习指南。ITIL作为...
标题中的“初学certificate”指的是学习证书相关的知识,这通常涉及到网络安全、数据加密以及身份验证等领域。在IT行业中,证书,尤其是数字证书,是保障网络通信安全的重要工具。它们用于证明用户、服务器或设备的...
《数学建模-Certificate_30221.zip》...总的来说,"数学建模-Certificate_30221.zip"可能是一个重要的个人成就记录,反映了持证人在数学建模领域的学习和实践经历,对于学术研究、求职就业或进一步深造都具有积极意义。
【数学建模-certificate30875.zip】是一个压缩包文件,主要包含了一份名为“数学建模-certificate30875.pdf”的文档。这个文件很可能是与数学建模相关的学习资料或证书,标签为“资料”,暗示了它可能包含教育、学术...
这个文件的目的是提供一个官方的认可,证明个人在数学建模方面的学习和成就。下面我们将深入探讨数学建模的基本概念、重要性以及它在实际问题解决中的应用。 数学建模是应用数学的一个分支,通过数学语言和方法来...
《数学建模-28895certificate.zip》是一个压缩包文件,主要包含了一份名为“数学建模-28895certificate.pdf”的文档。这个文件极有可能是关于数学建模竞赛的证书或者相关学习资料,鉴于其标签为“资料”,我们可以...
《数学建模-31348certificate.zip》是一个压缩包文件,主要包含了一份名为“数学建模-31348certificate.pdf”的文档。这个文件很可能是与数学建模相关的学习资料,尤其是证书或者成果证明,可能涉及到参赛者在数学...
这个压缩包包含的四个文件——sasbase123.pdf、SAS ADV 50_2.pdf、SAS BASE 50.pdf、SAS ADV 50_1.pdf,很可能是为了帮助考生准备SAS认证考试而精心编排的试题集或者学习指南。 首先,我们要了解SAS(Statistical ...
"Labview Certificate Prepare"的标题表明这是一个关于准备Labview认证考试的学习资源包,包含了帮助考生熟悉考试内容和格式的内部资料。 在描述中提到的“Nation Instrument 内部资料”可能包含了一系列的教程、...