之前想实现像U盾一样的功能,用户连接到系统需要提供系统识别的身份信息,也就是提供一个由系统签发的证书,所以就想

了解https相关的东西,结果发现这套东西对于我来说太复杂,想要实现的功能可以通过其他的方式来实现,这里就简单的记录一下我

了解的关于https的内容并做一下记录,以备以后的查阅

https是基于SSL(secure socket layer)和TLS(transport Layer security),tls是ssl的继任者,这两种协议是应用层协议,提供了更多的加密方式,对应用层的数据进行加密,

包括协商加密算法,验证证书等等。

其中主要涉及到的知识点包括 对称加密和非对称加密, SSL或者TLS在真正传递数据的时候用的是对称加密,而非对称加密只用在了加密对称加密的秘钥上面,因为对称加密一般都比较慢(如RSA)。

证书:一般是https证书,我们都知道在对称加密算法中包括一个公钥和一个私钥,公钥是公开的,而私钥是私密的,证书中存放的是公钥,以及相应的主机域名,比如我们有一个主机是www.example.com ,我们为其生成公钥,然后放到证书中。

证书的颁发者是各个权威机构,我们如果想要证书就要向他们申请(当然,是收费的),证书的验证是一项很复杂的任务,每个机构都有一个根证书(root certificate),主流浏览器中都保存了,如果我们在访问一个https网站时,发送过来的证书通过本地的根证书验证成功则能正常访问,如果各个根证书验证失败那么浏览器就会产生警告信息。

自定义证书,如果是自己测试或是内部用的话,可以自己给自己颁发证书,自己生成证书有很多工具,长用的就是openssl,可以到其官网查看。另一种是在java中使用的,keytool工具,在jdk的bin目录下面,后面介绍keytool工具以及相关的概念。

为了更快的了解ssl,https证书等的概念,我们通过分别为apache web服务器和tomcat添加https支持来更清楚的了解他们之间的关系以及区别。

为 apache httpd服务器添加https支持:

我们都知道httpd的主配置文件时httpd.conf,为了使其支持https,我们首先需要打开ssl所需要的模块,具体哪些,请自行google,然后将ssl的配置文件包含进来

如:Include conf/extra/httpd-ssl.conf

然后我们只需要为SSLCertificateFile和SSLCertificateKeyFile指定好相应的值,这就是我们要用openssl生成的,从名字我们可以看出来SSLCertificate是证书,SSLCertificate是私钥文件。

我们都知道ssl是采用非对称加密的,如RSA等等,公钥是放在证书中的,私钥也可以放在证书中,也可以单独放在一个地方我们这里单独放在一个地方。

现在我们用openssl来生成需要的东西

用openssl生成私钥:openssl genrsa -out server.key 1024

可以给这个私钥文件添加密码:openssl genrsa -des3 1024 > server.key,如果用了
#密码那么在生成证书时要输入密码,而且每次重启httpd服务时也要输入密码
#如果不想要密码了,也可以删除: openssl rsa -in server.key -out server.key

生成证书(指定私钥文件时server.key): openssl req -new -x509 -key server.key -out server.crt

到此证书和私钥都生成好了,放到相应的地方然后将SSLCertificateFile和SSLCertificateKeyFile指定好就行了

tomcat添加ssl支持

在java中使用ssl一般就使用keytool工具了

先解释一下,在前面用openssl生成证书的时候很简单,先生成私钥,然后生成证书,最后指定文件位置就完成了,但在java中证书和私钥是放在一个叫keystore的容器里的,keystore是一个文件,由密码保护,在访问的时候要提供密码,其中每个证书都有一个别名(alias),如果不指定别名,默认就是mykey,而且私钥是不能导出的(为了安全考虑),不像httpd中私钥也是单独放在一个文件中的。

生成 keytool -genkey -v -alias tomcat -keypass 123456 -keyalg RSA -keystore j:/tmp/https2/tomcat.keystore -validity 365

要你提供的first name and last name 就是域名

这样就生成的公钥和私钥,都存放在tomcat.keystore中的tomcat别名中,然后就要修改tomcat配置文件server.xml了

<Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol" maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
  keystoreFile="j:/tmp/https2/tomcat.keystore" keystorePass="changeit"
   keyPass="123456"
  keyAlias="tomcat"
                 clientAuth="false" sslProtocol="TLS" />

将这个Connector的注释去掉,各个属性的意思应该很清楚了,这里就不罗嗦了。

记录一下我做ssl双向验证的程序,最后在用浏览器访问的时候老是说证书验证失败,但是用java程序直接访问时成功了,看来还是没有完全弄明白,这里先记录一下以后再研究

//服务器端证书
keytool -genkey -v -alias tomcat -keypass 123456 -keyalg RSA -keystore j:/tmp/https2/tomcat.keystore -validity 365

//生成客户端证书
keytool -genkey -v -alias clientkey -keyalg RSA -storetype PKCS12 -keystore j:/tmp/https2/kevin_com.pk12
//格式转换(将此格式转为证书,这样才能存入服务器端)
keytool -export -alias clientkey -keystore j:/tmp/https2/kevin_com.pk12 -storetype PKCS12 -storepass changeit -rfc -file j:/tmp/https2/clientkey.cer

//将客户端证书导入到服务器端证书库
keytool -import -v -file  j:/tmp/https2/clientkey.cer -keystore j:/tmp/https2/tomcat.keystore

//把服务器端证书导出来,然后再安装到浏览器
keytool -export -alias tomcat -keystore j:/tmp/https2/tomcat.keystore  -file j:/tmp/https2/tomcat.cer

这里在生成客户端证书的时候采用了稍微复杂一点的方式,其实是可以直接生成的,tomcat的配置

<Connector port="443" protocol="org.apache.coyote.http11.Http11Protocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
  keystoreFile="j:/tmp/https2/tomcat.keystore" keystorePass="changeit"
  truststoreFile="j:/tmp/https2/tomcat..keystore"  truststorePass="changeit"
  keyPass="123456"
  keyAlias="tomcat"
               clientAuth="true" sslProtocol="TLS" />

tomcat的配置文件多了一个 truststoreFile和strustorePass就是收信任的客户端的证书,如果这里客户端没有提供证书或者提供的证书在truststore中不存在,那么就会其禁止访问

public class HttpsConnTest {private static class TrustAnyTrustManager implements X509TrustManager{@Overridepublic void checkClientTrusted(X509Certificate[] chain, String authType)throws CertificateException {System.out.println("in checkClientTrusted");}@Overridepublic void checkServerTrusted(X509Certificate[] chain, String authType)throws CertificateException {System.out.println("in checkServerTrusted");}@Overridepublic X509Certificate[] getAcceptedIssuers() {System.out.println("in getAcceptedIssuers");return new X509Certificate[]{};}}private static class TrustAnyHostnameVerifier implements HostnameVerifier{@Overridepublic boolean verify(String hostname, SSLSession session) {System.out.println(" in verify");return true;}}public static void accessWithKeyStoreValidate() throws Exception{ KeyStore keyStore = KeyStore.getInstance("JKS");//纵然keyStore是从这个地址加载的,但是验证主机的时候还是从当前所使用的jre里面加载的,这里要特别注意// 因为jdk有两个jre,其中的lib/security/下面都有certs文件// keytool -import -file J:/tmp/httpskey/server.crt -alias starryconnCrt -keystore ../lib/security/cacerts//导入的时候指定keystore文件,不然默认就导入到home目录下面去了
//      keyStore.load(new FileInputStream("C:/Users/凯文/.keystore")  , null);
//      keyStore.load(new FileInputStream("J:/tmp/httpskey/kevin_com_crt")  , null);//        keyStore.load(new FileInputStream("    ")  , null);keyStore.load(new FileInputStream("J:/tmp/https2/trustclients.keystore")  , null);
//      Certificate  c = keyStore.getCertificate("client1");KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");kmf.init(keyStore, "123456".toCharArray());SSLContext sslContext = SSLContext.getInstance("SSLv3");sslContext.init(kmf.getKeyManagers(), null, null);HttpsURLConnection console = (HttpsURLConnection)new URL("https://www.kevin.com/index.jsp").openConnection();console.setSSLSocketFactory(sslContext.getSocketFactory());console.connect();DataInputStream is = new DataInputStream(console.getInputStream());StringBuffer sb  = new StringBuffer();String str = null;while( (str = is.readLine()) != null){sb.append(str);}System.out.println("received data : " + sb.toString());}public static void main(String[] args) throws Exception{
//      URL url = new URL("https://www.starryconn.com/");
//      URLConnection  conn = url.openConnection();
//      DataInputStream stream = new DataInputStream( conn.getInputStream());
//      System.out.println( stream.readLine() );accessWithKeyStoreValidate();//     System.out.println(KeyManagerFactory.getDefaultAlgorithm());
//      main2(null);if(1==1)return;Provider [] providers = Security.getProviders();for(Provider p : providers ){
//          System.out.println(p.getName());}FileInputStream is = new FileInputStream("C:\\Users\\凯文\\.keystore");// FileInputStream is = new FileInputStream("J:/my_programfiles/jdk7/jre/lib/security/cacerts");KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());keyStore.load(is, null);Enumeration<String> alias = keyStore.aliases();while(alias.hasMoreElements()){System.out.println(alias.nextElement());}KeyStore.ProtectionParameter protParam = new KeyStore.PasswordProtection(null);String a = "starryconncrt";KeyStore.TrustedCertificateEntry pkEntry = (KeyStore.TrustedCertificateEntry)keyStore.getEntry(a, null);System.out.println(pkEntry.getTrustedCertificate().getPublicKey());
//      String format = pkEntry.getPrivateKey().getFormat();
//      String algorithm = pkEntry.getPrivateKey().getAlgorithm();
//      System.out.println("format:"+ format + " , algorithm:"+ algorithm);//    Certificate cert = keyStore.getCertificate(a);}public static void main2(String[] args) {InputStream in = null;OutputStream out = null;byte [] buffer = new byte[4096];StringBuffer returnStr = new StringBuffer();try{SSLContext sslContext = SSLContext.getInstance("SSL");sslContext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());URL console = new URL("https://www.starryconn.com/");HttpsURLConnection conn = (HttpsURLConnection)console.openConnection();conn.setSSLSocketFactory(sslContext.getSocketFactory());conn.setHostnameVerifier(new TrustAnyHostnameVerifier());conn.connect();InputStream is = conn.getInputStream();DataInputStream inData = new DataInputStream(is);String str = null;while((str = inData.readLine()) != null){returnStr.append(str);}conn.disconnect();}catch(Exception e){e.printStackTrace();}System.out.println("received data: "+ returnStr.toString());}
}

先留作记录,以后再慢慢研究

2015年3月9日添加

看到了一篇很详细的文章,用openssl实现了apache httpd的ssl双向验证,客户端是浏览器,注:浏览器只接受pkcs12的文件格式,pkcs12是将证书和证书的秘钥打包的一种格式,下面我将我实现时的openssl命令写下来供参考,总的流程是这样:

1、 创建根证书 (Common Name可以写为 *.example.com)

2、创建服务器证书 (如果是web服务器可以写成 www.example.com) , 并用根证书为其签名生成证书

3、创建客户端证书(Common Name可以随便填,如client1等),并用根证书签名,然后导出为pkcs12格式

4、将根证书和客户端证书一起导入到浏览器中,注意,根证书是要加入到受信任的根证书这一栏中

create CA private key : openssl genrsa -out private/ca.key.pem 2048
create CA csr: openssl req -new -key private/ca.key.pem -out private/ca.csrgenerate CA certificate : openssl x509 -req -days 3650 -sha1 -extensions v3_ca -signkey private/ca.key.pem -in private/ca.csr -out cert/ca.cer
show it : openssl x509 -noout -text -in cert/ca.cer create server private key: openssl genrsa -out  private/server.key.pem 2048
create csr: openssl req -new -key private/server.key.pem -out private/server.csr
sign server with ca to get the certificate:
openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA cert/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/server.csr -out cert/server.cercreate client :
private key : openssl genrsa -out private/client.key.pem 2048
create csr : openssl req -new -key private/client.key.pem -out private/client.csr
sign it with ca:
openssl x509 -req -days 3650 -sha1 -extensions v3_req -CA cert/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/client.csr -out cert/client.cer
convert to pkcs12 in order import to browser:
openssl pkcs12 -export -clcerts -inkey private/client.key.pem -in cert/client.cer -out cert/client.p12

参考的博客原文:http://www.iteye.com/topic/1131378

http://stackoverflow.com/questions/1666052/java-https-client-certificate-authentication/1710543#1710543

http://stackoverflow.com/questions/589622/ssl-question-how-does-a-root-ca-verify-a-signature

还有一些概念性的东西也贴在这里,以供参考:

PKI标准可以分为第一代和第二代标准[12]。
第一代PKI标准主要包括美国RSA公司的公钥加密标准(Public Key Cryptography Standards,PKCS)系列、国际电信联盟的ITU-T X.509、IETF组织的公钥基础设施X.509(Public Key Infrastructure X.509,PKIX)标准系列、无线应用协议(Wireless Application Protocol ,WAP)论坛的无线公钥基础设施(Wireless Public Key Infrastructure,WPKI)标准等。第一代PKI标准主要是基于抽象语法符号(Abstract Syntax Notation One,ASN.1)编码的,实现比较困难,这也在一定程度上影响了标准的推广。
第二代PKI标准是在2001年,由微软、VeriSign和webMethods三家公司发布了XML密钥管理规范(XML Key Management Specification,XKMS),被称为第二代PKI标准。XKMS由两部分组成:XML密钥信息服务规范(XML Key Information Service Specification,X-KISS)和XML密钥注册服务规范(XML Key Registration Service Specification,X-KRSS)。X-KISS定义了包含在XML-SIG元素中的用于验证公钥信息合法性的信任服务规范;使用X-KISS规范,XML应用程序可通过网络委托可信的第三方CA处理有关认证签名、查询、验证、绑定公钥信息等服务。X-KRSS则定义了一种可通过网络接受公钥注册、撤销、恢复的服务规范;XML应用程序建立的密钥对,可通过X-KRSS规范将公钥部分及其它有关的身份信息发给可信的第三方CA注册。X-KISS和X-KRSS规范都按照XML Schema 结构化语言定义,使用简单对象访问协议(SOAP V1.1)进行通信,其服务与消息的语法定义遵循Web服务定义语言(WSDL V1.0)。目前XKMS已成为W3C的推荐标准,并已被微软、VeriSign等公司集成于他们的产品中(微软已在ASP.net中集成了XKMS,VeriSign已发布了基于Java的信任服务集成工具包TSIK)。
CA中心普遍采用的规范是X.509[13]系列和PKCS系列,其中主要应用到了以下规范:
1.X.209(1988) 
ASN.1是描述在网络上传输信息格式的标准方法。它有两部分:第一部份(ISO 8824/ITU X.208)描述信息内的数据、数据类型及序列格式,也就是数据的语法;第二部分(ISO 8825/ITU X.209)描述如何将各部分数据组成消息,也就是数据的基本编码规则。 
ASN.1原来是作为X.409的一部分而开发的,后来才独立地成为一个标准。这两个协议除了在PKI体系中被应用外,还被广泛应用于通信和计算机的其他领域。 
2.X.500(1993) 
X.500是一套已经被国际标准化组织(ISO)接受的目录服务系统标准,它定义了一个机构如何在全局范围内共享其名字和与之相关的对象。X.500是层次性的,其中的管理域(机构、分支、部门和工作组)可以提供这些域内的用户和资源信息。在PKI体系中,X.500被用来惟一标识一个实体,该实体可以是机构、组织、个人或一台服务器。X.500被认为是实现目录服务的最佳途径,但X.500的实现需要较大的投资,并且比其他方式速度慢;而其优势具有信息模型、多功能和开放性。 
3.X.509(1993) 
X.509是由国际电信联盟(ITU-T)制定的数字证书标准。在X.500确保用户名称惟一性的基础上,X.509为X.500用户名称提供了通信实体的鉴别机制,并规定了实体鉴别过程中广泛适用的证书语法和数据接口。 
X.509的最初版本公布于1988年。X.509证书由用户公共密钥和用户标识符组成。此外还包括版本号、证书序列号、CA标识符、签名算法标识、签发者名称、证书有效期等信息。这一标准的最新版本是X.509 v3,它定义了包含扩展信息的数字证书。该版数字证书提供了一个扩展信息字段,用来提供更多的灵活性及特殊应用环境下所需的信息传送。 
4.PKCS系列标准 
PKCS是由美国RSA数据安全公司及其合作伙伴制定的一组公钥密码学标准,其中包括证书申请、证书更新、证书作废表发布、扩展证书内容以及数字签名、数字信封的格式等方面的一系列相关协议。到1999年底,PKCS已经公布了以下标准: 
PKCS#1:定义RSA公开密钥算法加密和签名机制,主要用于组织PKCS#7中所描述的数字签名和数字信封。 
PKCS#3:定义Diffie-Hellman密钥交换协议。 
PKCS#5:描述一种利用从口令派生出来的安全密钥加密字符串的方法。使用MD2或MD5 从口令中派生密钥,并采用DES-CBC模式加密。主要用于加密从一个计算机传送到另一个计算机的私人密钥,不能用于加密消息。 
PKCS#6:描述了公钥证书的标准语法,主要描述X.509证书的扩展格式。 
PKCS#7:定义一种通用的消息语法,包括数字签名和加密等用于增强的加密机制,PKCS#7与PEM兼容,所以不需其他密码操作,就可以将加密的消息转换成PEM消息。 
PKCS#8:描述私有密钥信息格式,该信息包括公开密钥算法的私有密钥以及可选的属性集等。 
PKCS#9:定义一些用于PKCS#6证书扩展、PKCS#7数字签名和PKCS#8私钥加密信息的属性类型。 
PKCS#10:描述证书请求语法。 
PKCS#11:称为Cyptoki,定义了一套独立于技术的程序设计接口,用于智能卡和PCMCIA卡之类的加密设备。 
PKCS#12:描述个人信息交换语法标准。描述了将用户公钥、私钥、证书和其他相关信息打包的语法。 
PKCS#13:椭圆曲线密码体制标准。 
PKCS#14:伪随机数生成标准。 
PKCS#15:密码令牌信息格式标准。 
5.OCSP在线证书状态协议 
OCSP(Online Certificate Status Protocol)[14]是IETF颁布的用于检查数字证书在某一交易时刻是否仍然有效的标准。该标准提供给PKI用户一条方便快捷的数字证书状态查询通道,使PKI体系能够更有效、更安全地在各个领域中被广泛应用。 
6.LDAP 轻量级目录访问协议 
LDAP规范(RFC1487)简化了笨重的X.500目录访问协议,并且在功能性、数据表示、编码和传输方面都进行了相应的修改。1997年,LDAP第3版本成为互联网标准。目前,LDAP v3已经在PKI体系中被广泛应用于证书信息发布、CRL信息发布、CA政策以及与信息发布相关的各个方面。

关于SSL以及https的相关信息相关推荐

  1. nginx http强制跳转https 配置相关信息

    跳转方式有两种 1.rewrite 方式 rewrite ^(.*) https://$server_name$1 permanent; 2.return方式 return 301 https://$ ...

  2. SSL协议(HTTPS) 握手、工作流程详解(双向HTTPS流程)

    SSL协议的工作流程: 服务器认证阶段:1)客户端向服务器发送一个开始信息"Hello"以便开始一个新的会话连接:2)服务器根据客户的信息确定是否需要生成新的主密钥,如需要则服务器 ...

  3. 申请https证书相关说明

    当下的互联网应用如果是外网访问,一般都是https方式访问,需申请https证书 目录 Why https ? What is https? 1. A 通过浏览器访问 B 服务端443端口,并随身携带 ...

  4. mysql如何查看数据库相关信息

    使用MySQL时,需要了解当前数据库的情况,例如当前的数据库大小.字符集.用户等等.下面总结了一些查看数据库相关信息的命令 原文网址: https://www.cnblogs.com/jiangxia ...

  5. 通俗易懂的TCP,SSL以及HTTPS的连接建立过程详解

    可以参考B站的一个视频,把TLS/SSL的连接建立过程降解的非常透彻.配合这篇博客食用更佳.一遍不懂请多看几遍,很有用! 1 说明 1.1 对称加密的和非对称加密 在数字加密算法中,通过可划分为对称加 ...

  6. SSL证书包含了哪些信息?

    如果一个网站.系统或平台安装部署了SSL证书,并且证书正常运行,那么我们就可以从浏览器地址栏找到该网站的证书,并查看其内容.以沃通CA官网使用的证书为例,来探讨从SSL证书中能看出哪些信息. 所有安装 ...

  7. 非对称加密、数字摘要、数字签名、数字证书、SSL、HTTPS及其他

    本文原文连接:http://blog.csdn.net/bluishglc/article/details/7585965 转载请注明出处! 对于一般的开发人员来说,很少需要对安全领域内的基础技术进行 ...

  8. 和安全有关的那些事(非对称加密、数字摘要、数字签名、数字证书、SSL、HTTPS及其他)

    本文原文连接:http://blog.csdn.net/bluishglc/article/details/7585965 转载请注明出处! 对于一般的开发人员来说,很少需要对安全领域内的基础技术进行 ...

  9. 获取access中表的相关信息

    就用到两条.net自带的获取数据库信息的语句 OleDbConnection con = new OleDbConnection(connection); // OleDB数据库连接实例 // 获取数 ...

  10. 获取Java系统相关信息

    1 package com.test; 2 3 import java.util.Properties; 4 import java.util.Map.Entry; 5 6 import org.ju ...

最新文章

  1. C#中两个窗体间的数据传递
  2. 组件间数据交互——父组件向子组件传值( props属性值类型) 子组件向父组件传值-携带参数 || 非父子组件间传值
  3. 小米手环无法模拟门卡_MIUI12轻体验:关于模拟门禁卡,你想知道的都在这里
  4. Linux高级字符设备之Poll操作
  5. ubuntu16定时任务crontab
  6. React版本更新及升级须知(持续更新)
  7. 牛客假日团队赛5J 护城河 bzoj 1670: [Usaco2006 Oct]Building the Moat护城河的挖掘 (凸包的周长)...
  8. 100 万在中国不同地方能活多久?
  9. Linux:ps命令以及进程状态详解
  10. FAIR 何恺明、Piotr、Ross等新作,MAE才是YYDS!仅用ImageNet1K,Top-1准确率87.8%!
  11. 一个光标绘制问题的解决过程
  12. DiskFileUpload上传与Spring的CommonsMultipartResolver上传对比
  13. 兄弟們,彈鋼琴不是只有有錢人可以玩的
  14. DH算法图解+数学证明
  15. COM口(DB9) 连 RJ45 线序
  16. c语言数组的地址传递,c语言函数传递数组_c语言函数数组地址传递没有输出
  17. Shifterator库 | 词移图分辨两文本用词风格差异
  18. 树形结构的处理——组合模式(一)
  19. android 8代号,Android 8.0来了:代号或是“奥利奥”
  20. 卡通爆炸logo展示片头片尾动态视频AE模板

热门文章

  1. 干货 | 还不了解中介调节模型?赶紧收藏本文吧。
  2. office word 文件未找到:MathPage.WLL
  3. matlab图形黎曼几何,黎曼几何不一致的定理—元数学与元物理学(22)
  4. 浏览器市场占有率最新分析
  5. 进程管理——PV操作
  6. 暑假视力如何保护?护眼台灯可以保护视力
  7. 微信开放平台申请流程讲解与注意事项(未完待续)
  8. 《知行合一王阳明》阅读心得
  9. 软件测试测试常见分类有哪些?
  10. 《编码:隐匿在计算机软硬件背后的语言》一书勘误