收藏 分享(赏)

数字证书双向认证.docx

上传人:scg750829 文档编号:7150571 上传时间:2019-05-07 格式:DOCX 页数:28 大小:1,021.01KB
下载 相关 举报
数字证书双向认证.docx_第1页
第1页 / 共28页
数字证书双向认证.docx_第2页
第2页 / 共28页
数字证书双向认证.docx_第3页
第3页 / 共28页
数字证书双向认证.docx_第4页
第4页 / 共28页
数字证书双向认证.docx_第5页
第5页 / 共28页
点击查看更多>>
资源描述

1、1.CA认证原理1.1.概念数字证书为发布公钥提供了一种简便的途径,其数字证书则成为加密算法以及公钥的载体,依靠数字证书,我们可以构建一个简单的加密网络应用平台,数字证书就好比我们生活中的身份证,现实中,身份证由公安机关签发,而网络用户的身份凭证由数字证书颁发认证机构CA 签发,只有经过 CA 签发的证书在网络中才具备可认证性,CA 并不是一个单纯的防御手段,它集合了多种密码学算法: 消息摘要算法:MD5、和 SHA(对数字证书本省做摘要处理,用于验证数据完整性服务器) 对称加密算法:RC2、RC4、IDEA、DES、AES(对数据进行加密/解密操作,用于保证数据保密性服务) 非对称加密算法:

2、RSA、DH(对数据进行加密/解密操作,用于保证数据保密性服务) 数字签名算法:RSA、DSA(对数据进行签名/验证操作,保证数据的完整性和抗否认性)。证书的签发过程实际上是对申请数字证书的公钥做数字签名,证书的验证过程实际上是对数字证书的公钥做验证签名,其中还包含证书有效期验证,通过 CA 数字证书,我们对网络上传输的数据进行加密/解密和签名/验证操作,确保数据机密性、完整性、抗否认性、认证性,保证交易实体身份的真实性,保证网络安全性。所有证书有多种文件编码格式,主要包括: CER 编码(规范编码格式):是数字证书的一种编码格式,它是 BER(基本编码格式)的一个变种,比 BER 规定得更严

3、格 DER(卓越编码格式):同样是 BER 的一个变种,与 CER 的不同在于,DER 使用定长模式,而 CER 使用变长模式。所有证书都符合公钥基础设施(PKI)制定的 ITU-T X509 国际标准,PKCS(公钥加密标准)由 RSA 实验室和其他安全系统开发商为促进公钥密码的发展而制定的一系列标准,比如:PKCS#7(密码消息语法标准-文件后缀名:.p7b、.p7c、.spc)、PKCS#10(证书请求语法标准-文件后缀名:.p10、.csr)、PKCS#12(个人信息交换语法标准-文件后缀名:.p12、.pfx)等,在获得数字证书后,可以将其保存在电脑中,也可以保存在 USB Key

4、等相应的设备中。1.2. SSL/TLS 原理我们先来看一个简单的证书机构签发的流程:这里的认证机构如何是证书申请者本身,将获得自签名证书。当客户端获得服务器下发的数字证书后,即可使用数字证书进行加密交互:数字证书的应用环境是在 https 安全协议中,使用流程远比上述加密交互流程复杂,但是相关操作封装在传输层,对于应用层透明,在 https 安全协议中使用非对称加密算法交换密钥,使用对称加密算法对数据进行加密/解密操作,提高加密/解密效率。要获得数字证书,我们需要使用数字证书管理工具:KeyTool 和 OpenSSL 构建 CSR(数字证书签发申请),交由 CA 机构签发,形成最终的数字证

5、书,这里我们不对 KeyTool 做讲解(KeyTool 不含有根证书,因此 KeyTool 没有办法作为CA),网上资料对 keytool 讲解的也挺多的,我们下面针对 OpenSSL 进行讲解。在我们搭建 OPEN SSL 环境前,我们要知道 HTTPS 协议和 SSL/TLS 协议,简单的说,HTTPS 就是 HTTP+SSL(secure socket layer)/TLS(Transport Layer Security)协议,HTTPS 协议为数字证书提供了最佳的应用环境,HTTPS 协议一般在服务器中配置,如 HTTP 服务器 APACHE、TOMCAT 等。SSL:位于 TCP

6、/IP 中的网络传输层,作为网络通讯提供安全以及数据完整性的一种安全协议。TLS:作为 SSL 协议的继承者,成为下一代网络安全性和数据完整性安全协议SSL 共有 3 个版本:1.0、2.0、3.0,TLS 也有 1.0、2.0、3.0,通常我们说的SSL/TLS 协议指的是 SSL3.0/TLS1.0 的网络传输层安全协议SSL/TLS 协议分为两层:记录协议:建议在可靠的传输协议之上,为高层协议提供数据封装、压缩、加密等基本功能的支持握手协议:建立在 SSL 记录协议之上,用于在实际的数据传输开始前,通讯双方进行身份认证、协商加密算法、交换加密密钥等经过了 SSL/TLS 握手协议交互后,

7、数据交互双方确定了本次会话使用的对称加密算法以及密钥,就可以开始进行加密数据交互了,以下是握手协议服务器端和客户端构建加密交互的相关流程图:协商算法1、 随机数为后续构建密钥准备2、 其他信息包括服务器证书、甚至包含获取客户端证书的请求验证算法如果服务器端回复客户端时带有其他信息,则进入数字证书验证阶段客户端验证服务器端证书:服务器端验证客户端证书:产生密钥当服务器端和客户端经过上述流程后,就开始密钥构建交互了,服务器端和客户端最初需要主密钥为构建会话密钥做准备:上述 5、6 不存在次序关系,因为是异步完成会话密钥完成上述主密钥构建操作后,服务器端和客户端将建立会话密钥,完成握手协议:加密交互

8、上述服务器端和客户端完成了握手协议以后就进入正式会话阶段,如果上述流程中有任何一端受到外界因素干扰发生异常,则重新进入协商算法阶段,下面流程表现进入会话阶段后,服务器端和客户端将使用会话密钥进行加密交互:2.OpenSSL实现双向认证OpenSSL 是一个开放源代码软件包,实现了 SSL 以及相关加密技术,是最常用的证书管理工具,OpenSSL 功能远胜于 KeyTool,可用于根证书(KeyTool 不含有,因此 KeyTool 没有办法作为 CA)、服务器证书、客户证书的管理。在 OpenSSL 官网下载:http:/www.openssl.org/source 下载最新的源码,官网还提供

9、了 windows 版的二进制发行版地址:http:/ 选择适合自己操作系统的版本进行下载后,安装操作与普通软件一样,没有什么区别 设置环境变量:打开配置文件 openssl.cfg(%OpenSSL_Home%binopenssl.cfg),找到配置CA_default:变量 dir,它指向的是 CA 工作目录,可以对其进行修改2.2.Cmd创建命令整个 bat 文件的创建过程我们可以把它想象成这样一种场景:高考结束,教育局来颁发毕业证书给各个学校,各个学校在把证书发给学生,具体步骤如下:1) 教育局先有空白证书了2) 教育局又有自己的公章3) 让各个学校可以拥有毕业证发放申请4) 对空白的

10、毕业证盖上了教育局的公章,并可以交给已经申请的学校5) 申请的学校拿到了盖有教育局的毕业证后,准备对其盖上自己的公章6) 学校在教育局已经盖上教育局公章的毕业证上又盖上了自己学校的公章7) 准备把毕业证发给学校申请毕业的学生们8) 申请毕业的学生拿取自己的学生证和身份证准备领取毕业证9) 来到学校教务处,填写单据申请学校发放毕业证10) 教育局已经转交学校来发放毕业证,此时学校把毕业证发放给申请学生11) 学生认为盖有教育局的公章和学校的公章的毕业证是有效的/构建ca子目录(证书创建时,用到下述目录 ,最终在certs目录中获得证书文件)echo 构建已发型证书存放目录 certsmkdir

11、certsecho 构建新证书存放目录 newcertsmkdir newcertsecho 构建私钥存放目录 privatemkdir privateecho 构建证书吊销列表存放目录 crlmkdir cr1 /构建相关文件,完成后可以进行证书的构建和签发工作echo 构建索引文件 index.txtecho 0index.txtecho 构建序列号文件 serialecho 01serial/构建根证书 echo 构建随机数 private/.randopenssl rand -out private/.rand 1000/构建根证书私钥echo 构建根证书私钥 private/ca.k

12、ey.pemopenssl genrsa -aes256 -out private/ca.key.pem 2048/完成密钥构建操作后,需要生成根证书签发申请文件ca.csr/生成根证书签发申请echo 生成根证书签发申请 private/ca.csropenssl req -new -key private/ca.key.pem -out private/ca.csr -subj “/C=CN/ST=HUBEI/L=WUHAN/O=YALE/OU=YALE/CN=*.qiujinyong.org“/执行完后此处又要输入根证书密码/得到根证书签发申请文件后,可以将其发送给CA机构签发,也可以自

13、行签发根证书echo 签发根证书 private/ca.cer openssl x509 -req -days 1000 -sha1 -extensions v3_ca -signkey private/ca.key.pem -in private/ca.csr -out certs/ca.cer/执行完后此处又要输入根证书密码echo 根证书转换 private/ca.p12openssl pkcs12 -export -cacerts -inkey private/ca.key.pem -in certs/ca.cer -out certs/ca.p12/执行完后此处又要输入根证书密码/构

14、建服务器证书echo 构建服务器私钥 private/server.key.pemopenssl genrsa -aes256 -out private/server.key.pem 2048/服务器证书签发申请echo 生成服务器证书签发申请 private/server.csropenssl req -new -key private/server.key.pem -out private/server.csr -subj “/C=CN/ST=HUBEI/L=WUHAN/O=YALE/OU=YALE/CN=“/执行完后此处又要输入根证书密码/根证书签发服务器证书 echo 签发服务器证书

15、private/server.ceropenssl x509 -req -days 3650 -sha1 -extensions v3_req -CA certs/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/server.csr -out certs/server.cer/执行完后此处又要输入根证书密码/将OpenSSL产生的数字证书转换为PKCS#12 编码格式echo 服务器证书转换 private/server.p12openssl pkcs12 -export -clcert

16、s -inkey private/server.key.pem -in certs/server.cer -out certs/server.p12/执行完后此处又要输入根证书密码/构建客户证书echo 产生客户私钥 private/client.key.pemopenssl genrsa -aes256 -out private/client.key.pem 2048/执行完后此处又要输入根证书密码/产生客户证书签发申请echo 生成客户证书签发申请 client.csropenssl req -new -key private/client.key.pem -out private/cli

17、ent.csr -subj “/C=CN/ST=HUBEI/L=WUHAN/O=YALE/OU=YALE/CN=qiujinyong“/执行完后此处又要输入根证书密码/根证书签发客户证书echo 签发客户证书 certs/client.ceropenssl x509 -req -days 3650 -sha1 -extensions v3_req -CA certs/ca.cer -CAkey private/ca.key.pem -CAserial ca.srl -CAcreateserial -in private/client.csr -out certs/client.cer/执行完后

18、此处又要输入根证书密码/将获得客户证书转换JAVA 语言可以识别的PKCS#12编码格式echo 客户证书转换 certs/client.p12openssl pkcs12 -export -inkey private/client.key.pem -in certs/client.cer -out certs/client.p12/完成了双向认证的所需的全部证书echo 根密钥库转换 ca.keystorekeytool -importkeystore -v -srckeystore certs/ca.p12 -srcstorepass 123456 -destkeystore certs/

19、ca.keystore -srcstoretype pkcs12 -deststorepass 123456keytool -list -keystore certs/ca.keystore -v -storepass 123456echo 服务器密钥库转换 server.keystorekeytool -importkeystore -v -srckeystore certs/server.p12 -srcstorepass 123456 -destkeystore certs/server.keystore -srcstoretype pkcs12 -deststorepass 12345

20、6keytool -list -keystore certs/server.keystore -v -storepass 123456echo 客户密钥库转换 client.keystorekeytool -importkeystore -v -srckeystore certs/client.p12 -srcstorepass 123456 -destkeystore certs/client.keystore -srcstoretype pkcs12 -deststorepass 123456keytool -list -keystore certs/client.keystore -v

21、-storepass 123456pauseecho on2.3.文件生成通过上述语句我们生成了以下几个“一级”文件以及文件夹:Certs 文件夹下又生成了:Private 文件夹下又生成了2.4.证书导入我们使用 ca.p12、server.p12、client.p12 个人信息交换文件构建双向认证。在验证操作之前,我们先导入 ca.p12、client.p12 文件,ca.p12 文件是 ca 根证书的个人信息交换文件:双击”ca.p12”或者点击在浏览器“工具“-“internet 选项“-“内容“中的“证书“-“导入“点击“下一步”后,“浏览”按钮时,指定个人信息交换文件格式(*.p1

22、2;*.pfx), 选择“ca.p12 的所在位置”:输入私钥的密码选择“将所有的证书放入下列存储”:点击“浏览”,选择“受信任的根证书颁发机构”:点击“下一步”,然后点击“完成”导入”client.p12”文件:导入 clinet.p12 文件的方式和 ca.p12 文件方式基本相似,只是在证书存储时,选择“个人”:2.5.服务器配置将”ca.p12” 、 ”server.p12”文件复制到 tomcat 的 conf 目录下:我们在 tomcat 的 server.xml 文件中配置双向认证:这里的密钥库文件参数 keystoreFile 指向 server.p12 文件,密钥库密码参数

23、keystorePass 值为”123456” ,密钥库类型参数 keystoreType 值为”PKCS12”,因为双向认证服务区分信任库文件和密钥库文件,此时,server.p12 文件将作为密钥库文件,而 ca.p12 文件则作为信任库文件,因此,信任库文件参数 truststoreFile 指向 ca.p12 文件,信任库密码参数 truststorePass 值为”123456” ,信任库类型参数 truststoreType 值为“pkcs12” ,clientAuth 的值为”true” ,这是打开双向认证的关键一步,port 默认为 8443,现在修改为 443,这样就省去我们

24、在地址栏中输入端口号。2.6.效果展现双向认证成功的标志是浏览器出现地址栏出现 图标2.7.服务器端获得客户端证书index.jsp 页面request属性信息数字证书信息浏览器访问路径:https:/www.zlex.org:8444/CA/3.代码整理3.1.获得 KeyStore/* 获得KeyStore* * param keyStorePath* 密钥库路径* param password* 密码* return KeyStore 密钥库* throws Exception*/private static KeyStore getKeyStore(String keyStorePat

25、h, String password)throws Exception / 实例化密钥库KeyStore ks = KeyStore.getInstance(“PKCS12“);/ 获得密钥库文件流FileInputStream in = new FileInputStream(keyStorePath);/ 加载密钥库ks.load(in, password.toCharArray();/ 关闭密钥库文件流in.close();return ks;3.2.由 KeyStore获得私钥/* 由KeyStore获得私钥* * param keyStorePath* 密钥库路径* param al

26、ias* 别名* param password* 密码* return PrivateKey 私钥* throws Exception*/public static PrivateKey getPrivateKeyByKeyStore(String keyStorePath,String alias, String password) throws Exception / 获得密钥库KeyStore ks = getKeyStore(keyStorePath, password);/ 获得私钥return (PrivateKey) ks.getKey(alias, password.toCha

27、rArray();3.3.获得 Certificate/* 获得Certificate* * param certificatePath* 证书路径* return Certificate 证书* throws Exception*/private static X509Certificate getCertificate(String certificatePath)throws Exception / 实例化证书工厂CertificateFactory certificateFactory = CertificateFactory.getInstance(“X.509“);/ 取得证书文件

28、流FileInputStream in = new FileInputStream(certificatePath);/ 生成证书Certificate certificate = certificateFactory.generateCertificate(in);/ 关闭证书文件流in.close();return (X509Certificate) certificate;3.4.由 Certificate获得公钥/* 由Certificate获得公钥* * param certificatePath* 证书路径* return PublicKey 公钥* throws Exceptio

29、n*/public static PublicKey getPublicKeyByCertificate(String certificatePath)throws Exception / 获得证书Certificate certificate = getCertificate(certificatePath);/ 获得公钥return certificate.getPublicKey();3.5.私钥加密,公钥解密/* 私钥加密* * param data* 待加密数据* param keyStorePath* 密钥库路径* param alias* 别名* param password*

30、密码* return byte 加密数据* throws Exception*/public static byte encryptByPrivateKey(byte data, String keyStorePath,String alias, String password) throws Exception / 取得私钥PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath, alias,password);/ 对数据加密Cipher cipher = Cipher.getInstance(privateKey.getAl

31、gorithm();cipher.init(Cipher.ENCRYPT_MODE, privateKey);return cipher.doFinal(data);/* 公钥解密* * param data* 待解密数据* param certificatePath* 证书路径* return byte 解密数据* throws Exception*/public static byte decryptByPublicKey(byte data, String certificatePath)throws Exception / 取得公钥PublicKey publicKey = getPu

32、blicKeyByCertificate(certificatePath);/ 对数据加密Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm();cipher.init(Cipher.DECRYPT_MODE, publicKey);return cipher.doFinal(data);3.6.公钥加密,私钥解密/* 公钥加密* * param data* 待加密数据* param certificatePath* 证书路径* return byte 加密数据* throws Exception*/public static b

33、yte encryptByPublicKey(byte data, String certificatePath)throws Exception / 取得公钥PublicKey publicKey = getPublicKeyByCertificate(certificatePath);/ 对数据加密Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm();cipher.init(Cipher.ENCRYPT_MODE, publicKey);return cipher.doFinal(data);/* 私钥解密* * param

34、 data* 待解密数据* param keyStorePath* 密钥库路径* param alias* 别名* param password* 密码* return byte 解密数据* throws Exception*/public static byte decryptByPrivateKey(byte data, String keyStorePath,String alias, String password) throws Exception / 取得私钥PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,

35、alias,password);/ 对数据加密Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm();cipher.init(Cipher.DECRYPT_MODE, privateKey);return cipher.doFinal(data);3.7.私钥签名/* 签名* * param keyStorePath* 密钥库路径* param alias* 别名* param password* 密码* return byte 签名* throws Exception*/public static byte sign(byte

36、 sign, String keyStorePath, String alias,String password, String certificatePath) throws Exception / 获得证书X509Certificate x509Certificate = getCertificate(certificatePath);/ 构建签名,由证书指定签名算法Signature signature = Signature.getInstance(x509Certificate.getSigAlgName();/ 获取私钥PrivateKey privateKey = getPriv

37、ateKeyByKeyStore(keyStorePath, alias,password);/ 初始化签名,由私钥构建signature.initSign(privateKey);signature.update(sign);return signature.sign();3.8.公钥认证/* 验证签名* * param data* 数据* param sign* 签名* param certificatePath* 证书路径* return boolean 验证通过为真* throws Exception*/public static boolean verify(byte data, b

38、yte sign,String certificatePath) throws Exception / 获得证书X509Certificate x509Certificate = (X509Certificate) getCertificate(certificatePath);/ 由证书构建签名Signature signature = Signature.getInstance(x509Certificate.getSigAlgName();/ 由证书初始化签名,实际上是使用了证书中的公钥signature.initVerify(x509Certificate);signature.upd

39、ate(data);return signature.verify(sign);3.9.生成证书证书实体参数配置public interface CAConfig /* C*/String CA_C = “CN“;/* ST*/String CA_ST = “BJ“;/* L*/String CA_L = “BJ“;/*/ String CA_O = “SICCA“;/* CA_ROOT_ISSUER*/String CA_ROOT_ISSUER=“C=CN,ST=BJ,L=BJ,O=SICCA,OU=SC,CN=SICCA“;/* CA_DEFAULT_SUBJECT*/String CA_

40、DEFAULT_SUBJECT=“C=CN,ST=BJ,L=BJ,O=SICCA,OU=SC,CN=“;String CA_SHA=“SHA256WithRSAEncryption“;证书生成类public class BaseCert /* BouncyCastleProvider*/static Security.addProvider(new BouncyCastleProvider();protected static KeyPairGenerator kpg = null;public BaseCert() try / 采用 RSA 非对称算法加密kpg = KeyPairGener

41、ator.getInstance(“RSA“);/ 初始化为 1023 位kpg.initialize(1024); catch (NoSuchAlgorithmException e) e.printStackTrace();/* 生成 X509 证书* param user* return*/public X509Certificate generateCert(String user) X509Certificate cert = null;try KeyPair keyPair = this.kpg.generateKeyPair();/ 公钥PublicKey pubKey = ke

42、yPair.getPublic();/ 私钥PrivateKey priKey = keyPair.getPrivate();X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();/ 设置序列号certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis();/ 设置颁发者certGen.setIssuerDN(new X500Principal(CAConfig.CA_ROOT_ISSUER);/ 设置有效期certGen.setNo

43、tBefore(new Date(System.currentTimeMillis() - 50000);certGen.setNotAfter(new Date(System.currentTimeMillis() + 50000);/ 设置使用者certGen.setSubjectDN(new X500Principal(CAConfig.CA_DEFAULT_SUBJECT + user);/ 公钥certGen.setPublicKey(pubKey);/ 签名算法certGen.setSignatureAlgorithm(CAConfig.CA_SHA);cert = certGen

44、.generateX509Certificate(priKey, “BC“); catch (Exception e) System.out.println(e.getClass() + e.getMessage();return cert;4.附加4.1.Keytool生成米密钥库keytool -genkeypair -keyalg RSA -keysize 2048 -sigalg SHA1withRSA -validity 36000 -alias www.zlex.org -keystore zlex.keystore-dname “CN=www.zlex.org, OU=zlex, O=zlex, L=BJ, ST=BJ, C=CN“导出证书keytool -exportcert -alias www.zlex.org -keystre zlex.keystore -file zlex.cer -rfc -storepass 123456

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报