SSL/TLS 单双向认证代码示例
来源:互联网 发布:windows自带编程软件 编辑:程序博客网 时间:2024/06/13 03:44
采用SSL/TLS形式的安全链接,能防止数据传输过程中被截获修改等问题。
SSL算法简短说明:
对称加密算法:DES 3DES AES 客户端和服务端使用同一个密钥对消息进行加密解密。
非对称加密算法:RSA, 生成公钥和私钥,采用公钥加密,私钥解密。客户端和服务器端各自持有自己的私钥证书,相互信任对方的证书(证书都导入到了对方的私钥仓库)
速度上,对称加密算法比非对称加密算法要快。
下面使用jdk工具keytool生成服务端和客户端的密钥和证书,采用的是RSA的非对称加密形式。
生成服务器端证书仓库
keytool -genkey -alias serverks -keysize 2048 -validity 365 -keyalg RSA -dname "CN=localhost" -keypass serverpwd -storepass serverpwd -keystore D:/serverks.jks
生成服务器端证书
keytool -export -alias servercert -keystore D:/serverks.jks -storepass serverpwd -file D:/servercert.cer
生成客户端证书仓库
keytool -genkey -alias clientks -keysize 2048 -validity 365 -keyalg RSA -dname "CN=localhost" -keypass clientpwd -storepass clientpwd -keystore D:/clientks.jks
生成客户端证书
keytool -export -alias clientcert -keystore D:/clientks.jks -storepass clientpwd -file D:/clientcert.cer
上面四个命令就可以生成客户端和服务器端的证书和仓库了。
对于单项认证,客户端验证服务器端,服务器端不做验证情况,只需要将服务器端证书导入到客户端证书仓库。
对于双向认证,除了上面的导入操作外,还需要将客户端证书导入到服务器端证书仓库。
命令如下:
服务器端证书导入客户端证书仓库
keytool -import -trustcacerts -alias servercert2clientks -file D:/servercert.cer -storepass clientpwd -keystore D:/clientks.jks
客户端证书导入到服务器端证书仓库
keytool -import -trustcacerts -alias clientcert2serverks -file D:/clientcert.cer -storepass serverks -keystore D:/serverks.jks
上述命令解释:
keytool //java jdk自带工具
-genkey //生成key的命令参数
-alias //生成key别名
-keysize // key大小,2048
-validity //有效期,单位天
-keyalg //key的算法,本文采用RSA
-dname //key的信息串,CN=这里是域名,此外还有OU / O / L / S / C=CH 代表拥有者/归属/地区/城市/国家
-keypass // 生成key的密码,
-storepass //存储的密码
-keystore //生成key输出的路径和文件名
-export //导出证书
-import //导入证书
-file //导出的文件
下面是Java中SSLContext的生成过程:
单向SSL认证服务端代码(客户端对服务端证书进行验证,服务器端接受所有证书)
//获取X509算法的key管理工厂类KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");//获取keystore类型实例,jks类型KeyStore ks = KeyStore.getInstance("JKS");//读取服务器端的证书库InputStream in = ClassLoader.getSystemResourceAsStream("serverks.jks");//加载到keystore,第二个参数密码ks.load(in, "serverpwd".toCharArray());in.close();//初始化keymanager通过keystore和密码kmf.init(ks, "serverpwd".toCharArray());//获取sslcontext,SSL/TLSv1.xSSLContext serverContext = SSLContext.getInstance("TLSv1.2");//单项认证,客户端认证服务器,trustmanager为空,就是服务器端信任所有客户端证书serverContext.init(kmf.getKeyManagers(), null, null);
双向认证相比上面,只是让sslcontext的第二个信任证书参数传递不为空即可,代表服务器端新人的证书对象。//获取X509算法的key管理工厂类KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");//获取keystore类型实例,jks类型KeyStore ks = KeyStore.getInstance("JKS");//读取服务器端的证书库InputStream in = ClassLoader.getSystemResourceAsStream("serverks.jks");//加载到keystore,第二个参数密码ks.load(in, "serverpwd".toCharArray());in.close();//初始化keymanager通过keystore和密码kmf.init(ks, "serverpwd".toCharArray());//获取sslcontext,SSL/TLSv1.xSSLContext serverContext = SSLContext.getInstance("TLSv1.2");//获取x509信任证书工厂,并根据keystore初始化, 服务器端验证客户端证书是否有效TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");tmf.init(ks);//双向认证,此处多trustManagers参数serverContext.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);
对于TrustManager可以自己实现,但是一般很少自己实现,实现方式如下://获取X509算法的key管理工厂类KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");//获取keystore类型实例,jks类型KeyStore ks = KeyStore.getInstance("JKS");//读取服务器端的证书库InputStream in = ClassLoader.getSystemResourceAsStream("serverks.jks");//加载到keystore,第二个参数密码ks.load(in, "serverpwd".toCharArray());in.close();//初始化keymanager通过keystore和密码kmf.init(ks, "serverpwd".toCharArray());//获取sslcontext,SSL/TLSv1.xSSLContext serverContext = SSLContext.getInstance("TLSv1.2");//自定义实现证书验证X509TrustManager x509 = new X509TrustManager() {public X509Certificate[] getAcceptedIssuers() {return null;}/** * 服务器端检查 */public void checkServerTrusted(X509Certificate[] chain, String authType)throws java.security.cert.CertificateException {if (chain == null || chain.length == 0) {throw new IllegalArgumentException("X509Certificate chain cannot be null");}if (authType == null || authType.equals("")) {throw new IllegalArgumentException("X509Certificate authType cannot be null");}boolean isSucc = false;Principal p = null;for (X509Certificate x : chain) {p = x.getSubjectDN();//Principal getName 为keytool 中的-dname参数对应的值if (p != null && p.getName().contains("localhost")) {//这里只验证了-dName那个参数是否能识别isSucc = true;return ;}}if (!isSucc) {throw new java.security.cert.CertificateException("no authorizication");}}/** * 客户端检查 */public void checkClientTrusted(X509Certificate[] chain, String authType)throws java.security.cert.CertificateException {if (chain == null || chain.length == 0) {throw new IllegalArgumentException("X509Certificate chain cannot be null");}if (authType == null || authType.equals("")) {throw new IllegalArgumentException("X509Certificate authType cannot be null");}boolean isSucc = false;Principal p = null;for (X509Certificate x : chain) {p = x.getSubjectDN();if (p != null && p.getName().contains("localhost")) {isSucc = true;return ;}}if (!isSucc) {throw new java.security.cert.CertificateException("no authorizication");}}};//双向认证,自定义x509验证实现serverContext.init(kmf.getKeyManagers(), new TrustManager[]{x509}, null);
- SSL/TLS 单双向认证代码示例
- Java-JSSE-SSL/TLS编程代码实例-双向认证
- Java-JSSE-SSL/TLS编程代码实例-双向认证
- Java-JSSE-SSL/TLS编程代码实例-双向认证
- SSL单双向认证
- SSL单双向认证
- SSL/TLS 双向认证(一) -- SSL/TLS工作原理
- SSL/TLS 双向认证(一) -- SSL/TLS工作原理
- SSL-TLS 双向认证(一) -- SSL-TLS工作原理
- SSL/TLS单向双向认证原理
- SSL/TLS双向认证实现(JAVA、TOMCAT)
- Node.JS、Socket.IO 的 SSL/TLS 双向认证笔记
- GCDAsyncSOcket使用及其SSL/TLS双向认证的实现
- eclipse实现SSL单/双向认证
- eclipse实现SSL单/双向认证
- SSL/TLS 双向认证(二) -- 基于mosquittto的MQTT双向认证
- SSL/TLS 双向认证(三) -- ESP8266与mosquitto的MQTT双向认证
- SSL/TLS 双向认证(二) -- 基于mosquittto的MQTT双向认证
- 解决git每次pull或者push时输入密码问题
- JavaScript中的字符串拼接以及截取
- 首届女生科技节 | 女生也可以离科技很近!
- 由某习题联想到的二叉树广义表表示法求深度
- 创建邮件内容
- SSL/TLS 单双向认证代码示例
- 面试
- Python文件读取
- 在 SSH 中使用 RSA 和 DSA 认证(详解)
- leetcode 486. Predict the Winner 动态规划DP + 递归
- Python之Socket自动重连
- PLC 几个知识点
- 移动端图片上传方法
- Mysql命令大全(完整版)