前面简单的学习了证书的一些概念。继续学习证书的相关知识及其应用。
提到证书的应用,可以在输入的地址栏看到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是自己写的类。
分享到:
相关推荐
puppet_certificate学习资料
tensorflow certificate 开发者认证 深度学习证书 Google认证 5道建模问题 文本分类图像分类时序预测 参考 本人已获得认证 模型搭建 保存为h5格式 keras numpy pandas 自然语言处理 祝你100美元花得值!该证书旨在让...
记录了AWS开发助理级认证考试(DVA-C01)的一些笔记,主要记录的是一些比较容易搞错或者说比较重要的概念。
数据分析证书 我的数据分析证书学习历程 课程内容: 第一个里程碑 :check_mark_button: :check_mark_button: :check_mark_button: :check_mark_button: :check_mark_button: 第二个里程碑(Todo)
记录了AWS云从业者认证考试(CLF-C01)的一些笔记,主要记录的是一些比较容易搞错或者说比较重要的概念。
从学习Tensorflow 2.0 课程1: 课程2: 课程3: 课程4: 注意:训练并保存所有模型,并将其用于考试 在考试中 阅读 设置pyCharm和环境 阅读 二。 参加考试 考试将在5个小时内完成(我大约需要100分钟) 您有5个...
IBM的此专业证书将帮助有兴趣从事数据科学或机器学习职业的任何人发展与职业相关的技能和经验。 成为一名数据科学家需要博士学位,这是一个神话。 任何对学习充满热情的人都可以获得此专业证书-无需具备计算机科学...
斯坦福机器学习课程octave3.8.2工具提交补丁 Are you getting an error about "peer certificates"? You will need to install (this) patch if you are using Windows,
IBM Rational DOORS在iso26262 功能安全领域的实施认证说明,可以快速学习如何配置26262在工具中的实现
n public key certificate 公钥证书 n data confidentiality 数据保密 n hybrid cryptosystem(digital envelope) 混合密码 系统(数字信封) n data integrity 数据完整性 n HMAC n digital signature n ...
您将向 Google 员工学习,他们的数据分析基础是他们职业生涯的起点。 每周少于 10 小时,您可以在不到 6 个月的时间内完成证书。 您将为包括初级或副数据分析师、数据库管理员等在内的工作做好准备。 完成证书后,...
用于学习Linux的入门和一些简单的操作,方便新手入门
笔记我学到的是AWS认证解决方案架构师助理实践考试[警告:本书包含一些过时的信息] 认证解决方案架构师官方研究 我尚未学习的内容,但我认为这很好,因为它已针对新的考试格式进行了更新-SAA-C02 最终AWS认证解决...
斯坦福大学的机器学习(Coursera) 吴国安教授介绍“机器学习是使计算机在不经过明确编程的情况下运行的科学。...内容演讲幻灯片编程项目证书My certificate : : 参考Machine Learning - Stanford : :
您将使用Python之类的编程语言掌握机器学习和深度学习的基本概念,包括有监督和无监督的学习。 您将应用流行的机器学习和深度学习库(例如SciPy,ScikitLearn,Keras,PyTorch和Tensorflow)解决涉及对象识别,...
Tensorflow-开发人员证书 本系列包括文章,项目和概念,这将需要您自己成为。... 通过测试先睹为快,您需要通过提交保存的模型来提交整个机器学习模型。如果您听不懂我要说的内容,我们将在后续的讲座中介绍该主题。
RPA v11 学习课题 & 答案,V11 课程内的答题,RPA Developer Advance Certificate of Completion
urlread, curl, urlreadwrite, peer certificate, CA certificate, unsupported protocol, JSONparser ...here are some issues you can check. Are you using Octave 4.0.0? You will need to install this ...
用java swing写的批量上传组件。分享给大家一起学习,有不足的地方,大家一起完善。呵呵
IBM的此专业证书将帮助有兴趣从事数据科学或机器学习职业的任何人发展与职业相关的技能和经验。 成为一名数据科学家需要博士学位,这是一个神话。任何对学习充满热情的人都可以获得此专业证书-无需具备计算机科学或...