CA认证原理以及实现(上)

转载自:https://blog.csdn.net/lujiancs/article/details/38487235

原理基础

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

证书的签发过程实际上是对申请数字证书的公钥做数字签名,证书的验证过程实际上是对数字证书的公钥做验证签名,其中还包含证书有效期验证,通过CA数字证书,我们对网络上传输的数据进行加密/解密和签名/验证操作,确保数据机密性、完整性、抗否认性、认证性,保证交易实体身份的真实性,保证网络安全性。

 

所有证书有多种文件编码格式,主要包括:
CER编码(规范编码格式):是数字证书的一种编码格式,它是BER(基本编码格式)的一个变种,比BER规定得更严格
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等相应的设备中。

 

我们先来看一个简单的证书机构签发的流程:

这里的认证机构如何是证书申请者本身,将获得自签名证书。


当客户端获得服务器下发的数字证书后,即可使用数字证书进行加密交互:

 

数字证书的应用环境是在https安全协议中,使用流程远比上述加密交互流程复杂,但是相关操作封装在传输层,对于应用层透明,在https安全协议中使用非对称加密算法交换密钥,使用对称加密算法对数据进行加密/解密操作,提高加密/解密效率

 

要获得数字证书,我们需要使用数字证书管理工具:KeyTool和OpenSSL构建CSR(数字证书签发申请),交由CA机构签发,形成最终的数字证书,这里我们不对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/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握手协议交互后,数据交互双方确定了本次会话使用的对称加密算法以及密钥,就可以开始进行加密数据交互了,以下是握手协议服务器端和客户端构建加密交互的相关流程图:

协商算法

1、 随机数为后续构建密钥准备
2、 其他信息包括服务器证书、甚至包含获取客户端证书的请求

 

验证算法
如果服务器端回复客户端时带有其他信息,则进入数字证书验证阶段
客户端验证服务器端证书:

 

服务器端验证客户端证书:

 

产生密钥
当服务器端和客户端经过上述流程后,就开始密钥构建交互了,服务器端和客户端最初需要主密钥为构建会话密钥做准备:

上述5、6不存在次序关系,因为是异步完成

 

会话密钥
完成上述主密钥构建操作后,服务器端和客户端将建立会话密钥,完成握手协议:

 

加密交互
上述服务器端和客户端完成了握手协议以后就进入正式会话阶段,如果上述流程中有任何一端受到外界因素干扰发生异常,则重新进入协商算法阶段,下面流程表现进入会话阶段后,服务器端和客户端将使用会话密钥进行加密交互:

 

代码解释
在JAVA 6 以上版本中提供了完善的数字证书管理的实现,我们不需要关注相关具体算法,仅通过操作密钥库和数字证书就可以完成相应的加密/解密和签名/验证操作,密钥库管理私钥,数字证书管理公钥,私钥和密钥分属消息传递两方,进行加密消息的传递。
因此,我们可以将密钥库看做私钥相关操作的入口,数字证书则是公钥相关操作的入口:

Java代码 复制代码 收藏代码
  1. /****  
  2.      * 获得私钥,获得私钥后,通过RSA算方法实现进行"私钥加密,公钥解密"和"公钥加密,私钥解密"操作  
  3.      * @param keyStorePath 密钥库路径  
  4.      * @param alias 别名  
  5.      * @param password 密码  
  6.      * @return  私钥   
  7.      */  
  8.     private static PrivateKey getPrivateKeyByKeyStore(String keyStorePath,String alias,String password)throws Exception{   
  9.         //获得密钥库   
  10.         KeyStore ks = getKeyStore(keyStorePath,password);   
  11.         //获得私钥   
  12.         return  (PrivateKey)ks.getKey(alias, password.toCharArray());   
  13.            
  14.     }   
  15.        
  16.     /****  
  17.      * 由Certificate获得公钥,获得公钥后,通过RSA算方法实现进行"私钥加密,公钥解密"和"公钥加密,私钥解密"操作  
  18.      * @param certificatePath  证书路径  
  19.      * @return 公钥  
  20.      */  
  21.     private static PublicKey getPublicKeyByCertificate(String certificatePath)throws Exception {   
  22.         //获得证书   
  23.         Certificate certificate = getCertificate(certificatePath);   
  24.         //获得公钥   
  25.         return certificate.getPublicKey();   
  26.     }   
  27.        
  28.     /****  
  29.      * 加载数字证书,JAVA 6仅支持x.509的数字证书  
  30.      * @param certificatePath  证书路径  
  31.      * @return   证书  
  32.      * @throws Exception  
  33.      */  
  34.     private static Certificate getCertificate(String certificatePath) throws Exception{   
  35.         //实例化证书工厂   
  36.         CertificateFactory certificateFactory = CertificateFactory.getInstance("x.509");   
  37.         //取得证书文件流   
  38.         FileInputStream in = new FileInputStream(certificatePath);   
  39.         //生成证书   
  40.         Certificate certificate = certificateFactory.generateCertificate(in);   
  41.         //关闭证书文件流   
  42.         in.close();   
  43.         return certificate;   
  44.     }   
  45.        
  46.     /****  
  47.      * 获得Certificate  
  48.      * @param keyStorePath 密钥库路径  
  49.      * @param alias 别名  
  50.      * @param password  密码  
  51.      * @return  证书  
  52.      * @throws Exception  
  53.      */  
  54.     private static Certificate getCertificate(String keyStorePath,String alias,String password) throws Exception{   
  55.         //由密钥库获得数字证书构建数字签名对象   
  56.         //获得密钥库   
  57.         KeyStore ks = getKeyStore(keyStorePath,password);   
  58.         //获得证书   
  59.         return ks.getCertificate(alias);   
  60.     }   
  61.        
  62.     /****  
  63.      * 加载密钥库,加载了以后,我们就能通过相应的方法获得私钥,也可以获得数字证书  
  64.      * @param keyStorePath 密钥库路径  
  65.      * @param password 密码  
  66.      * @return  密钥库  
  67.      * @throws Exception  
  68.      */  
  69.     private static KeyStore getKeyStore(String keyStorePath,String password) throws Exception{   
  70.         //实例化密钥库   
  71.         KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());   
  72.         //获得密钥库文件流   
  73.         FileInputStream is = new FileInputStream(keyStorePath);   
  74.         //加载密钥库   
  75.         ks.load(is,password.toCharArray());   
  76.         //关闭密钥库文件流   
  77.         is.close();   
  78.         return ks;   
  79.     }   
  80.        
  81.     /****  
  82.      * 私钥加密  
  83.      * @param data  待加密的数据  
  84.      * @param keyStorePath  密钥库路径  
  85.      * @param alias  别名  
  86.      * @param password   密码  
  87.      * @return  加密数据  
  88.      * @throws Exception  
  89.      */  
  90.     public static byte[] encryptByPriateKey(byte[] data,String keyStorePath,String alias,String password) throws Exception{   
  91.         //获得私钥   
  92.         PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,password);   
  93.         //对数据加密   
  94.         Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());   
  95.         return cipher.doFinal(data);   
  96.     }   
  97.        
  98.     /****  
  99.      * 私钥解密  
  100.      * @param data  待解密数据  
  101.      * @param keyStorePath 密钥库路径  
  102.      * @param alias  别名  
  103.      * @param password  密码  
  104.      * @return  解密数据  
  105.      * @throws Exception  
  106.      */  
  107.     public static byte[] decryptByPrivateKey(byte[] data,String keyStorePath,String alias,String password) throws Exception{   
  108.         //取得私钥   
  109.         PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,password);   
  110.         //对数据解密   
  111.         Cipher cipher = Cipher.getInstance(privateKey.getAlgorithm());   
  112.         cipher.init(Cipher.DECRYPT_MODE,privateKey);   
  113.         return cipher.doFinal(data);   
  114.     }   
  115.        
  116.     /****  
  117.      * 公钥加密  
  118.      * @param data  等待加密数据  
  119.      * @param certificatePath  证书路径  
  120.      * @return   加密数据  
  121.      * @throws Exception  
  122.      */  
  123.     public static byte[] encryptByPublicKey(byte[] data,String certificatePath) throws Exception{   
  124.         //取得公钥   
  125.         PublicKey publicKey = getPublicKeyByCertificate(certificatePath);   
  126.         //对数据加密   
  127.         Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());   
  128.         cipher.init(Cipher.ENCRYPT_MODE,publicKey);   
  129.         return cipher.doFinal(data);   
  130.     }   
  131.        
  132.     /****  
  133.      * 公钥解密  
  134.      * @param data  等待解密的数据  
  135.      * @param certificatePath  证书路径  
  136.      * @return  解密数据  
  137.      * @throws Exception  
  138.      */  
  139.     public static byte[] decryptByPublicKey(byte[] data,String certificatePath)throws Exception{   
  140.         //取得公钥   
  141.         PublicKey publicKey = getPublicKeyByCertificate(certificatePath);   
  142.         //对数据解密   
  143.         Cipher cipher = Cipher.getInstance(publicKey.getAlgorithm());   
  144.         cipher.init(Cipher.DECRYPT_MODE, publicKey);   
  145.         return cipher.doFinal(data);   
  146.     }   
  147.        
  148.     /****  
  149.      * @param sign  签名  
  150.      * @param keyStorePath 密钥库路径  
  151.      * @param alias 别名  
  152.      * @param password 密码  
  153.      * @return 签名  
  154.      * @throws Exception  
  155.      */  
  156.     public static byte[] sign(byte[] sign,String keyStorePath,String alias,String password)throws Exception{   
  157.         //获得证书   
  158.         X509Certificate x509Certificate = (X509Certificate) getCertificate(keyStorePath,alias,password);   
  159.         //构建签名,由证书指定签名算法   
  160.         Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());   
  161.         //获取私钥   
  162.         PrivateKey privateKey = getPrivateKeyByKeyStore(keyStorePath,alias,password);   
  163.         //初始化签名,由私钥构建   
  164.         signature.initSign(privateKey);   
  165.         signature.update(sign);   
  166.         return signature.sign();   
  167.     }   
  168.        
  169.        
  170.     /****  
  171.      * 验证签名  
  172.      * @param data  数据  
  173.      * @param sign  签名  
  174.      * @param certificatePath  证书路径  
  175.      * @return  验证通过为真  
  176.      * @throws Exception  
  177.      */  
  178.     public static boolean verify(byte[] data,byte[] sign,String certificatePath) throws Exception{   
  179.         //获得证书   
  180.         X509Certificate x509Certificate = (X509Certificate)getCertificate(certificatePath);   
  181.         //由证书构建签名   
  182.         Signature signature = Signature.getInstance(x509Certificate.getSigAlgName());   
  183.         //由证书初始化签名,实际上是使用了证书中的公钥   
  184.         signature.initVerify(x509Certificate);   
  185.         signature.update(data);   
  186.         return signature.verify(sign);   
  187.     }   
  188.        
  189.     //我们假定密钥库文件yale.keystore存储在D盘根目录,数字证书文件yale.cer也存储在D盘根目录   
  190.     /****  
  191.      * 公钥加密---私钥解密  
  192.      * @throws Exception  
  193.      */  
  194.     public static void test1() throws Exception{   
  195.         System.err.println("公钥加密---私钥解密");   
  196.         String inputStr = "数字证书";   
  197.         byte[] data = inputStr.getBytes();   
  198.         //公钥加密   
  199.         byte[] encrypt = CertificateCoder.encryptByPublicKey(data, certificatePath);   
  200.         //私钥解密   
  201.         byte[] decrypt = CertificateCoder.decryptByPrivateKey(encrypt, keyStorePath, alias, password);   
  202.         String outputStr = new String(decrypt);   
  203.         System.err.println("加密前:\n" + inputStr);   
  204.         System.err.println("解密后:\n" + outputStr);   
  205.     }   
  206.        
  207.     /****  
  208.      * 私钥加密---公钥解密  
  209.      * @throws Exception  
  210.      */  
  211.     public static void test2()throws Exception{   
  212.         System.err.println("私钥加密---公钥解密");   
  213.         String inputStr = "数字签名";   
  214.         byte[] data = inputStr.getBytes();   
  215.         //私钥加密   
  216.         byte[] encodedData = CertificateCoder.encryptByPriateKey(data, keyStorePath, alias, password);   
  217.         //公钥加密   
  218.         byte[] decodeData = CertificateCoder.decryptByPublicKey(encodedData, certificatePath);   
  219.         String outputStr = new String (decodeData);   
  220.         System.err.println("加密前:\n" + inputStr);   
  221.         System.err.println("解密后:\n" + outputStr);   
  222.     }   
  223.        
  224.     public static void testSign()throws Exception{   
  225.         String inputStr = "签名";   
  226.         byte[] data = inputStr.getBytes();   
  227.         System.err.println("私钥签名---公钥验证");   
  228.         //产生签名   
  229.         byte[] sign = CertificateCoder.sign(data, keyStorePath, alias, password);   
  230.         System.err.println("签名:\n" + Hex.encodeHexString(sign));   
  231.         //验证签名   
  232.         boolean status = CertificateCoder.verify(data, sign, certificatePath);   
  233.         System.err.println("状态:\n " + status);   
  234.     } 
  • 9
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
电子商务:从广义上讲,电子商务是利用现有的计算机硬件设备、软件和网络基础设施,通过一定的协议连接起来的电子网络环境进行各种各样商务活动的总称。从狭义上讲,电子商务是在技术、经济高度发达的现代社会里,掌握信息技术和商务规划的人,系统化运用企业内联网(intranet)外联网(Extranet)及Internet等现代系统,进行高效率,低成本的商务活动。 Internet:连接了无数个遍及全球范围的广域网和局域网的互联网络。 B2B:商业机构(或企业、公司)使用Internet 或各种 商务网络向供应商(企业或公司)订货和付款。 B2C:电子商务是以Internet为主要手段,有商家或企业通过网站向消费者提供商品和服务的一种商务模式。 C2C:就是通过为买卖双方提供一个在线交易平台,使卖方可以主动提供商品上网拍卖,而买方可以自行选择商品进行竞价。 B2G:指政府部门与企业之间通过网络进行各项商务活动 。 电子支付:是客户首先以一定金额的现金或存款从发卡者处兑换得代表相同金额的数据,通过使用某些电子化方法将该数据直接转移给支付对象。 银行卡:是商业银行向社会公开发行,具有消费信用、转账结算、存取现金等全部或部分功能、作为支付结算工具的各类卡的统称。包括信用卡、借记卡等,客户可使用银行卡随时、随地完成在线支付操作,有关的个人信息、信用卡及密码信息,经过加密后直接传达到银行进行支付结算。 电子现金:是一种以数据形式流通、能被消费者和商家普遍接受、通过互联网购物时使用的数字化货币。用户可以随时通过互联网从银行账户上下载电子现金,从而保证了电子现金使用的便捷性。 电子支票:是一种借鉴纸张支票转移支付的优点,利用数字传递将钱款从一个账户转移到另一个账户的电子付款形式。这种电子支票的支付时在与商户及银行相连的网络上以密码方式传递的,大多数使用公用关键字加密签名或个人身份证号码(PIN)代替手写签名。 智能卡:是一种大小和普通卡片相仿的塑料卡片,内含一块直径1cm左右的硅芯片,具有存储信息和进行复杂运算的功能。 网上银行:是指通过因特网,将客户的电脑终端连接至银行网站,实现将银行服务直接送到客户办公室或家中的服务系统,使客户足不出户就可以享受到综合、统一、安全、实时的银行服务,包括提供对私、对公的各种零售和批发的全方位银行业务,还可以为客户提供跨国的支付与清算等其他的贸易、非贸易的银行业务服务。 物流:是物质资料从供给者到需求者的物理运动,主要是创造时间价值和场所价值,有时也创造一定加工价值的活动。 数据保密:保证在Internet网络上传递的数据信息不被第三方监视和窃取并使用该数据。 数据完整性:保证数据的完整性就是要保证在公共Internet网络上传递的数据信息不被篡改。 防火墙:是一种位于两个或多个网络间,实施网络之间访问控制的组件集合,是维护个人计算机或局域网安全的防护措施的总称。它是专门用来拦截、过滤不安全的信息,控制非法用户进入的软件。 CA证书:有认证授权中心(CA中心)发行的数字证书。 数字证书:是各实体(消费者、 户、企业、银行等)在网上进行信息交流及商务活动的身份证明,在电子交易的各个环节、交易各方都需要验证对方数字证书的有效性,从而解决相互间的信任问题。 电子商务网站设计原理重点全文共8页,当前为第1页。虚拟专用网:用于Internet交易的一种专用网络,在两个系统之间建立安全的信道(或隧道),用于电子数据交换。 电子商务网站设计原理重点全文共8页,当前为第1页。 信息检索:信息检索是指将信息按一定的方式组织和存储起来,并根据信息用户的需要找出有关信息的过程。所谓的电子商务信息检索,是指交易方或产品服务提供方根据自己的需求,按照一定的检索方式查找所需信息的过程。 指令:是指示计算机执行某种操作的命令。指令必须是二进制形式的代码,由操作码、操作数地址两部分构成。 程序:是由有序排列的指令组成的。 数据库:是长期储存在计算机内、有组织、可共分享的数据集合。 数据库管理系统DBMS:数据库管理系统是为数据库的建立、使用和维护配置的软件。 关系型数据库:关系型数据库是以关系数学模型来表示的数据。关系数学模型中以二维表的形式来描述数据。 数据仓库:(DW)是面向主题、集成、不可更新并随时间不断变化的数据的集合。数据仓库用来支持企业或组织的决策分析处理。 数据挖掘(DM):就是从大量、不完全、有噪声、模糊、随机的实际应用数据中,提取隐含在其中、人们事先不知道但又潜在有用的信息和知识的过程。 OSI/RM:是OSI在网络通信方面所定义的开放系统互连模型,1978年ISO(国际化标准组织)定义了一个开放协议标准。 TCP/IP:传输控制协议/互联网协议。TCP协议时IP协议的高层协议,TCP在IP之上提供了一个可靠的链接方式的协议。TCP
先运行safechat包里的greetigserver.class,之后运行greetingclient.class即可。 如遇报错,请参考:https://blog.csdn.net/fengzun_yi/article/details/104497160 实现过程: 1. 采用TCP通信协议完成接收者发送者双方的消息传递。 2. 利用Diffie-Hellman密钥交换协议生成对称加密通信的通信密钥。 3. 为防止中间人攻击,采用RSA非对称加密算法协助DH算法完成密钥交换。具体过程如下: a. 接收者与发送者双方各自利用RSA算法生成自己的公私钥,并生成数字证书,并在一个CA进行认证。 b. 在DH密钥交换阶段,A生成A的DH协商密钥用于发送给B,该密钥与接收方私钥生成最终通信密钥。发送DH密钥时,A先用自己的私钥加密DH协商密钥,再去CA获得一个真实的B的公钥,用B的公钥对加密过的协商密钥再做一次加密,发送给B。(因为是用B的公钥加密过,只有B有B的私钥,所以接收信息只有B自己可以解密查看,又因为是用A的私钥加密过的,只有A有A的私钥,所以只有用A的公钥可以进行解密,所以可以保证协商密钥确实是A发送过来的,而且发送的信息也无法被中间人解密。)B收到信息之后,先用自己的私钥解密,然后去CA获得A的公钥再对消息解密一次,获得A的DH密钥。B发给A的过程同上。 c. 之后双方执行DH生成本地密钥的过程。A利用B发送过来的密钥和A的DH私钥生成通信密钥。B利用A发送过来的密钥和B的DH私钥生成通信密钥。根据DH原理,两者生成的通信密钥是相同的。 4. 利用上一步生成的通信密钥,采用AES对称加密算法进行加密通信。 为了方便起见,并没用对A和B双方进行颁发证书的操作,A的公钥默认B已经从CA获得,B的公钥默认A已经从CA获得。并且采用java控制台交互,仅仅为演示原理及简单效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值