一 PKI概述
随着电子商务的迅速发展,信息安全已成为焦点问题之一,尤其是网上支付和网络银行对信息安全的要求显得更为突出。为了能在因特网上开展安全的电子商务活动,公开密钥基础设施(PKI,Public Key Infrastructure)逐步在国内外得到广泛应用。我们是否真的需要 PKI,PKI 究竟有什么用?
下面通过一个案例一步步地来剖析这个问题:甲想将一份合同文件通过 Internet 发给远在国外的乙,此合同文件对双方非常重要,不能有丝毫差错,而且此文件绝对不能被其他人得知其内容。如何才能实现这个合同的安全发送?
二 PKI应用
1 内容安全加密
最自然的想法是,甲必须对文件加密才能保证不被其他人查看其内容,那么,到底应该用什么加密技术,才能使合同传送既安全又快速呢?
可以采用一些成熟的对称加密算法,如 DES、3DES、RC5 等对文件加密。对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥,即加密密钥也可以用做解密密钥,这种方法在密码学中叫做对称加密算法。
2 加密文件
如果黑客截获此文件,是否用同一算法就可以解密此文件呢?
不可以,因为加密和解密均需要两个组件:加密算法和对称密钥,加密算法需要用一个对称密钥来解密,黑客并不知道此密钥。
3 使用非对称加密对称加密密钥
既然黑客不知密钥,那么乙怎样才能安全地得到其密钥呢?用电话通知,若电话被窃听,通过 Internet 发此密钥给乙,可能被黑客截获,怎么办?
方法是用非对称密钥算法加密对称密钥后进行传送。与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(Public Key)和私有密钥(Private Key)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫做非对称加密算法(公/私钥可由专门软件生成)。甲乙双方各有一对公/私钥,公钥可在 Internet 上传送,私钥自己保存。这样甲就可以用乙的公钥加密问题 1 中提到的对称加密算法中的对称密钥。即使黑客截获到此密钥,也会因为黑客不知乙的私钥,而解不开对称密钥,因此也解不开密文,只有乙才能解开密文。
4 非对称加密的缺点
既然甲可以用乙的公钥加密其对称密钥,为什么不直接用乙的公钥加密其文件呢?这样不仅简单,而且省去了用对称加密算法加密文件的步骤?
不可以这么做。因为非对称密码算法有两个缺点:加密速度慢,比对称加密算法慢10~100倍,因此只可用其加密小数据(如对称密钥),另外加密后会导致得到的密文变长。因此一般采用对称加密算法加密其文件,然后用非对称算法加密对称算法所用到的对称密钥。
5 数字签名
如果黑客截获到密文,同样也截获到用公钥加密的对称密钥,由于黑客无乙的私钥,因此他解不开对称密钥,但如果他用对称加密算法加密一份假文件,并用乙的公钥加密一份假文件的对称密钥,并发给乙,乙会以为收到的是甲发送的文件,会用其私钥解密假文件,并很高兴地阅读其内容,但却不知已经被替换。换句话说,乙并不知道这不是甲发给他的,怎么办?
答案是用数字签名证明其身份。数字签名是通过散列算法,如 MD5 、SHA-1 等算法从大块的数据中提取一个摘要。而从这个摘要中不能通过散列算法恢复出任何一点原文,即得到的摘要不会透露出任何最初明文的信息,但如果原信息受到任何改动,得到的摘要却肯定会有所不同。
因此甲可以对文件进行散列算法得到摘要,并用自己的私钥加密(因为非对称算法可逆,即用私钥可解开公钥加密的文件,反之亦然),这样即使黑客截获也无用。因为黑客不会从摘要内获得任何信息,但乙却不一样,他可用甲的公钥解密,得到其摘要,并对收到的文件(解密后的合同文件)也进行同样的散列算法,通过比较其摘要是否一样,就可得知此文件是否被篡改过(因为若摘要相同,则肯定信息未被改动,这是散列算法的特点)。这样不仅解决了证明发送人身份的问题,同时还解决了文件是否被篡改问题。
6 数字证书
通过对称加密算法加密其文件,再通过非对称算法加密其对称密钥,又通过散列算法证明其发送者身份和其信息的正确性,这样是否就万无一失了?
回答是否定的。问题在于乙并不能肯定他所用的所谓甲的公钥一定是甲的,解决办法是用数字证书来绑定公钥和公钥所属人。
数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件,是网络通信中标识通信各方身份信息的一系列数据,它提供了一种在 Internet 上验证身份的方式,其作用类似于司机的驾驶执照或日常生活中的身份证,人们可以在交往中用它来识别对方的身份。
最简单的证书包含一个公开密钥、名称以及证书授权中心的数字签名。一般情况下证书中还包括密钥的有效时间、发证机关(证书授权中心)名称、该证书的序列号等信息。它是由一个权威机构——CA机构,又称为证书授权(Certificate Authority)中心发放的。CA 机构作为电子商务交易中受信任的第三方,承担公钥体系中公钥的合法性检验的责任。CA 中心为每个使用公开密钥的用户发放一个数字证书,数字证书的作用是证明证书中列出的用户合法拥有证书中列出的公开密钥。CA 机构的数字签名使得攻击者不能伪造和篡改证书,CA 是 PKI 的核心,负责管理 PKI 结构下的所有用户(包括各种应用程序)的证书,把用户的公钥和用户的其他信息捆绑在一起,在网上验证用户的身份。
因为数字证书是公开的,就像公开的电话簿一样,在实践中,发送者(即甲)会将一份自己的数字证书的拷贝连同密文、摘要等放在一起发送给接收者(即乙),而乙则通过验证证书上权威机构的签名来检查此证书的有效性(只需用那个可信的权威机构的公钥来解密验证该证书上的签名就可以了),如果证书检查一切正常,那么就可以相信包含在该证书中的公钥的确属于列在证书中的那个人(即甲);如果文件被篡改,则无法通过该公钥解密加密文件。
7 时钟服务
至此似乎很安全了。但仍存在安全漏洞,例如:甲虽将合同文件发给乙,但甲拒不承认在签名所显示的那一时刻签署过此文件 (数字签名就相当于书面合同的文字签名) ,并将此过错归咎于电脑,进而不履行合同,怎么办 ?
解决办法是采用可信的时钟服务 (由权威机构提供) ,即由可信的时间源和文件的签名者对文件进行联合签名。在书面合同中,文件签署的日期和签名一样均是十分重要的防止文件被伪造和篡改的关键性内容 (例如合同中一般规定在文件签署之日起生效) 。在电子文件中,由于用户桌面时间很容易改变 (不准确或可人为改变) ,由该时间产生的时间戳不可信赖,因此需要一个第三方来提供时间戳服务(数字时间戳服务(DTS)是网上安全服务项目,由专门的机构提供)。此服务能提供电子文件发表时间的安全保护。
时间戳产生的过程为:用户首先将需要加时间戳的文件用哈希编码加密形成摘要,然后将该摘要发送到 DTS,DTS 在加入了收到文件摘要的日期和时间信息后再对该文件加密(数字签名),然后送回用户。因此时间戳 (time-stamp) 是一个经加密后形成的凭证文档,它包括三个部分:需加时间戳的文件的摘要,DTS 收到文件的日期和时间,DTS 的数字签名。由于可信的时间源和文件的签名者对文件进行了联合签名,进而阻止了文档签名的那一方 (即甲方) 在时间上欺诈的可能性,因此具有不可否认性。
8 私钥使用者认证
有了数字证书将公 / 私钥和身份绑定,又有权威机构提供时钟服务使其具有不可否认性,是不是就万无一失了 ? 不,仍然有问题。乙还是不能证明对方就是甲,因为完全有可能是别人盗用了甲的私钥 (如别人趁甲不在使用甲的电脑),然后以甲的身份来和乙传送信息,这怎么解决呢 ?
解决办法是使用强口令、认证令牌、智能卡和生物特征等技术对使用私钥的用户进行认证,以确定其是私钥的合法使用者。
解决这个问题之前我们先来看看目前实现的基于 PKI 的认证通常是如何工作的。以浏览器或者其他登记申请证书的应用程序为例说明,在第一次生成密钥的时候会创建一个密钥存储,浏览器用户会被提示输入一个口令,该口令将被用于构造保护该密钥存储所需的加密密钥。如果密钥存储只有脆弱的口令保护或根本没有口令保护,那么任何一个能够访问该电脑浏览器的用户都可以访问那些私钥和证书。在这种场景下,又怎么可能信任用 PKI 创建的身份呢?正因为如此,一个强有力的 PKI 系统必须建立在对私钥拥有者进行强认证的基础之上,现在主要的认证技术有:强口令、认证令牌、智能卡和生物特征(如指纹,眼膜等认证)。
以认证令牌举例:假设用户的私钥被保存在后台服务器的加密容器里,要访问私钥,用户必须先使用认证令牌认证(如用户输入账户名、令牌上显示的通行码和 PIN 等),如果认证成功,该用户的加密容器就下载到用户系统并解密。
9 总结
通过以上问题的解决,就基本满足了安全发送文件的需求。下面总结一下这个过程 ,对甲而言整个发送过程如下:
1、创建对称密钥(相应软件生成,并且是一次性的),用其加密合同,并用乙的公钥打包对称密钥。
2、创建数字签名,对合同进行散列算法(如 MD5 算法)并产生原始摘要,甲用自己的私钥加密该摘要(公/私钥既可自己创建也可由 CA 提供)。
3、最后,甲将加密后的合同、打包后的密钥、加密后的摘要,以及甲的数字证书(由权威机构 CA 签发)一起发给乙。
而乙接收加密文件后,需要完成以下动作:
1、接收后,用乙的私钥解密得到对称密钥,并用对称密钥解开加密的合同,得到合同明文。
2、通过甲的数字证书获得属于甲的公钥,并用其解开摘要(称做摘要1)。
3、对解密后的合同使用和发送者同样的散列算法来创建摘要(称做摘要2)。
4、比较摘要 1 和摘要 2,若相同,则表示信息未被篡改,且来自于甲。
甲乙传送信息过程看似并不复杂,但实际上它由许多基本成分组成,如:对称/非对称密钥密码技术、数字证书、数字签名、证书发放机构(CA)、公开密钥的安全策略等,这其中最重要、最复杂的是证书发放机构(CA)的构建。
在此强调下证书和签名:
证书实际对于非对称加密算法(公钥加密)来说的,一般证书包括公钥、姓名、数字签名三个部分。证书好比身份证,证书机构(ca)就好比是公安局,职责就是负责管理用户的证书也就是身份证。比如我的公钥是FrankKey,姓名是Frank Xu Lei。公安局可以给我登记,但是怎么保证我和别的Frank XuLei区别开呢,于是公安局(证书机构)就使用我的名字和密钥做了个组合,再使用一种哈希算法,得出一串值,来标识我的唯一性,这个值就是我的身份证号码,也就是证书里的数字签名(消息摘要),同时为了不能让黑客仿造数字证书,数字证书的发行者用自己的私钥对数字签名进行加密,这样,使用该数字证书的网络交易实体就可以用证书发行者的公钥进行解密验证。(即:数字签名的目的是证明自己的身份的确是真实的自己而非其他人,所以需要用自己的私钥进行加密,让使用者用公钥进行解密验证,从而从技术上杜绝了伪造自己的黑客。)
假设一个朋友给我写信,他就可以到公安局(证书机构)来查找我的身份证(证书)。上面包括我的个人信息,可以保证这个公钥就是我的。然后他把新建进行加密,邮寄给我。别人即使拆开我的信件,因为没有密钥进行解密,所以无法阅读我的信件内容。这样就保证了信息安全。
所以说加密不一定要证书,取决于你数据安全具体的需求。一般大型的电子商务网站都有自己特定的证书。证书管理的机构比较有名的就是VeriSign(可以说是互联网上的身份证管理局)。企业可以申请注册,它会给申请者生成特定的签名。我们自己的企业内部应用如果需要的话,可以在企业局域网内部建立企业私有的证书服务器,来产生和管理证书。其实X.509是由国际电信联盟(ITU-T)制定的一种定义证书格式和分布的国际标准(相当于制作身份证的规范)。为了提供公用网络用户目录信息服务,并规定了实体鉴别过程中广泛适用的证书语法和数据接口,X.509 称之为证书,或者说是身份证的一种形式,类似与我们现在的二代身份证,也是身份证的一种,根据特定的标准制作出来的。另外证书使用的时候还有有效期的限制,和我们的身份证的10年有效期一样。证书也可以设置有效期。
附:U盾的工作原理介绍
一、什么是U盾
U盾,即工行2003年推出并获得国家专利的客户证书USBkey,是工行为您提供的办理网上银行业务的高级别安全工具。它外形酷似U盘,像一面盾牌,时刻保护着您的网上银行资金安全。
从技术角度看,U盾是用于网上银行电子签名和数字认证的工具,它内置微型智能卡处理器,采用1024位非对称密钥算法对网上数据进行加密、解密和数字签名,确保网上交易的保密性、真实性、完整性和不可否认性。
二、工作原理
U盾又作移动数字证书,它存放着你个人的数字证书,并不可读取。同样,银行也记录着你的数字证书。
当你尝试进行网上交易时,银行会向你发送由时间字串,地址字串,交易信息字串,防重放攻击字串组合在一起进行加密后得到的字串A,你的U盾将跟据你的个人证书对字串A进行不可逆运算得到字串B,并将字串B发送给银行,银行端也同时进行该不可逆运算,如果银行运算结果和你的运算结果一致便认为你合法,交易便可以完成,如果不一致便认为你不合法,交易便会失败。(理论上,不同的字串A不会得出相同的字串B,即一个字串A对应一个唯一的字串B;但是字串B和字串A无法得出你的数字证书,而且U盾具有不可读取性,所以任何人都无法获行你的数字证书。并且银行每次都会发不同的防重放字串(随机字串)和时间字串,所以当一次交易完成后,刚发出的B字串便不再有效。综上所述,理论上U盾是绝对安全的****注意是理论上发生伪造概率大约为2的80次方分之一,但是如果有像变形金刚中的那种DNAbasecomputer的话。。。
推荐一本书籍,可以系统性学习:《信息安全原理与实践》。
三 详解公钥、私钥、数字证书的概念
1 加密和认证
首先我们需要区分加密和认证这两个基本概念。
加密是将数据资料加密,使得非法用户即使取得加密过的资料,也无法获取正确的资料内容,所以数据加密可以保护数据,防止监听攻击。其重点在于数据的安全性。身份认证是用来判断某个身份的真实性,确认身份后,系统才可以依不同的身份给予不同的权限。其重点在于用户的真实性。两者的侧重点是不同的。
2 公钥和私钥
公钥和私钥就是俗称的不对称加密方式,是从以前的对称加密(使用用户名与密码)方式的提高。
在现代密码体制中加密和解密是采用不同的密钥(公开密钥),也就是非对称密钥密码系统,每个通信方均需要两个密钥,即公钥和私钥,这两把密钥可以互为加解密。公钥是公开的,不需要保密,而私钥是由个人自己持有,并且必须妥善保管和注意保密。
公钥私钥的原则:一个公钥对应一个私钥。
密钥对中,让大家都知道的是公钥,只有自己知道的,是私钥。如果用其中一个密钥加密数据,则只有对应的那个密钥才可以解密。如果用其中一个密钥可以进行解密数据,则该数据必然是对应的那个密钥进行的加密。
用电子邮件的方式说明一下原理。
使用公钥与私钥的目的就是实现安全的电子邮件,必须实现如下目的:
1、我发送给你的内容必须加密,在邮件的传输过程中不能被别人看到。
2、必须保证是我发送的邮件,不是别人冒充我的。
要达到这样的目标必须发送邮件的两人都有公钥和私钥。
公钥,就是给大家用的,你可以通过电子邮件发布,可以通过网站让别人下载,公钥其实是用来加密/验章用的。私钥,就是自己的,必须非常小心保存,最好加上密码,私钥是用来解密/签章,首先就Key的所有权来说,私钥只有个人拥有。公钥与私钥的作用是:用公钥加密的内容只能用私钥解密,用私钥加密的内容只能用公钥解密。
比如说,我要给你发送一个加密的邮件。首先,我必须拥有你的公钥,你也必须拥有我的公钥。
首先,我用你的公钥给这个邮件加密,这样就保证这个邮件不被别人看到,而且保证这个邮件在传送过程中没有被修改。你收到邮件后,用你的私钥就可以解密,就能看到内容。
其次我用我的私钥给这个邮件加密,发送到你手里后,你可以用我的公钥解密。因为私钥只有我手里有,这样就保证了这个邮件是我发送的。
非对称密钥密码的主要应用就是公钥加密和公钥认证,而公钥加密的过程和公钥认证的过程是不一样的,下面我就详细讲解一下两者的区别。
基于公开密钥的加密过程
比如有两个用户Alice和Bob,Alice想把一段明文通过双钥加密的技术发送给Bob,Bob有一对公钥和私钥,那么加密解密的过程如下:
Bob将他的公开密钥传送给Alice。Alice用Bob的公开密钥加密她的消息,然后传送给Bob。Bob用他的私人密钥解密Alice的消息。Alice使用Bob的公钥进行加密,Bob用自己的私钥进行解密。
基于公开密钥的认证过程
身份认证和加密就不同了,主要用来鉴别用户的真伪。这里我们只要能够鉴别一个用户的私钥是正确的,就可以鉴别这个用户的真伪。
还是Alice和Bob这两个用户,Alice想让Bob知道自己是真实的Alice,而不是假冒的,因此Alice只要使用公钥密码学对文件签名发送给Bob,Bob使用Alice的公钥对文件进行解密,如果可以解密成功,则证明Alice的私钥是正确的,因而就完成了对Alice的身份鉴别。整个身份认证的过程如下:
Alice用她的私人密钥对文件加密,从而对文件签名。Alice将签名的文件传送给Bob。Bob用Alice的公钥解密文件,从而验证签名。Alice使用自己的私钥加密,Bob用Alice的公钥进行解密。
3 证书
1、什么是证书
数字证书是指在互联网通讯中标志通讯各方身份信息的一个数字认证,人们可以在网上用它来识别对方的身份。
数字证书的基本架构是公开密钥PKI,即利用一对密钥实施加密和解密。其中密钥包括私钥和公钥,私钥主要用于签名和解密,由用户自定义,只有用户自己知道;公钥用于签名验证和加密,可被多个用户共享。
2、什么是CA
CA是Certificate Authority的缩写,也叫“证书授权中心”。它是负责管理和签发证书的第三方机构,就好比例子里面的中介——C 公司。一般来说,CA必须是所有行业和所有公众都信任的、认可的。因此它必须具有足够的权威性。就好比A、B两公司都必须信任C公司,才会找 C 公司作为公章的中介。
3、什么是CA证书
CA 证书,顾名思义,就是CA颁发的证书。
4、什么是证书信任链
实际上,证书之间的信任关系,是可以嵌套的。比如,C 信任 A1,A1 信任 A2,A2 信任 A3…这个叫做证书的信任链。只要你信任链上的头一个证书,那后续的证书,都是可以信任滴。
5、什么根证书
于最顶上的树根位置的那个证书,就是“根证书”。除了根证书,其它证书都要依靠上一级的证书,来证明自己。那谁来证明“根证书”可靠?实际上,根证书自己证明自己是可靠的。
根证书是CA认证中心给自己颁发的证书,是信任链的起始点。安装根证书意味着对这个CA认证中心的信任。
6、什么是实体证书(用户证书)
实体证书是由根证书颁发的证书
7、单项认证
(1)申请证书:服务器生成请求文件Server.csr提交给CA
(2) 审核:CA审核服务器真实性
(3) 签发证书:证书内容就是上面提到的全部内容。到这里已经完成了整个SSL应用的部署,后面的步骤是具体的SSL工作流。
(4) TCP请求:当客户端要和服务器端通信,需要客户端发起一个TCP请求
(5) 返回证书:Server接收到Client的请求后会将证书Server.crt发送给Client。
(6) 验证证书:Client收到服务器证书Server.crt之后会对证书的签名解密,因此要用到对应的公钥,也就是CA的公钥,CA的公钥在CA证书里可以找到,CA证书是提前安装在客户端的。解密签名之后就可以校验摘要信息,域名信息等正确性
(7)协商通信密钥:如果证书校验通过,Server和Client将进行秘钥协商,然后Server和Client通信过程会采用对称秘钥加密。
单向认证和双向认证是什么?
大多情况下,尤其是web站点大多是单向认证即客户端只校验服务端真实性。双向认证在安全要求比较高的场景下需要双方都校验对方,两个过程极其类似,只是在Client认证完服务器证书后,Client会将自己的证书client.crt传给服务器,服务器验证通过后然后开始秘钥协商。
4 总结
根据非对称密码学的原理,每个证书持有人都有一对公钥和私钥,这两把密钥可以互为加解密。公钥是公开的,不需要保密,而私钥是由证书持有人自己持有,并且必须妥善保管和注意保密。
数字证书则是由证书认证机构(CA)对证书申请者真实身份验证之后,用CA的根证书对申请人的一些基本信息以及申请人的公钥进行签名(相当于加盖发证书机构的公章)后形成的一个数字文件。CA完成签发证书后,会将证书发布在CA的证书库(目录服务器)中,任何人都可以查询和下载,因此数字证书和公钥一样是公开的。
可以这样说,数字证书就是经过CA认证过的公钥,而私钥一般情况都是由证书持有者在自己本地生成的,由证书持有者自己负责保管。具体使用时,签名操作是发送方用私钥进行签名,接受方用发送方证书来验证签名;加密操作则是用接受方的证书进行加密,接受方用自己的私钥进行解密。
5 签名证书VS加密证书
从证书的用途来看,数字证书可以分为:
签名证书:主要用于对用户信息进行签名,以保证信息的不可否认性。
加密证书:主要用于对用户传送信息进行加密,以保证信息的真实性和完整性。
签名证书主要用于对用户信息进行签名,以保证信息的有效性和不可否认性;
加密证书主要用于对用户传送信息进行加密,以保证信息的保密性和完整性。
每个证书都包含一对密钥即签名公钥和签名私钥,加密公钥和加密私钥,将签名证书和加密证书的公钥公布于外。
签名时,用签名证书的私钥进行签名,其他用户可以利用公布于外网的签名公钥对签名进行验证。
加密时,用户B利用用户A公布于外网的加密公钥对信息进行加密传送给用户A,用户A利用自己的加密私钥对加密后的信息进行解密得到完整的明文信息。
6 数字证书格式 - 摘要
版本:该证书使用的是哪种版本的X.509标准。
序列号:本项是CA分配给每一个证书的唯一的数字型编号,证书序列号的长度在不同的 CA 系统中是可配置的。
签名算法:本项用来指定颁发机构CA签发证书时使用的签名算法。
颁发者:issuer 本项标识了颁发该证书的机构DN。
有效期:validity 本项是证书的有效期和终止日期。
主题:subject 证书拥有者的唯一是别名,这个字段必须是非空的。
有效的DN(Distinct Name)标识:
c | country code (一般是c=cn) |
---|---|
o | organization(组织) |
ou | organizational unit name(组织单位名) |
cn | common name (普通名) |
e | email (邮件地址) |
l | locality name (地址) |
st | state, or province name (国家或省份名) |
dc | domain Component (领域) |
uid | user id (用户标识符) |
t | title (标题) |
sn | device serial number name |
公钥 public key:本项用来标识公钥,公钥算法和公钥长度。 | |
微缩图算法:和证书本身没多大关系,就是哈希算法,通常用MD5或SHA1。 | |
微缩图:是指对整个证书进行hash运算之后生成的一段数据,就是对证书的哈希摘要。 | |
数字证书中主题(Subject)中字段的含义: | |
一般的数字证书产品的主题通常含有如下字段: | |
公用名称 (Common Name) 简称:CN 字段,对于 SSL 证书,一般为网站域名或IP地址;而对于代码签名证书则为申请单位名称;而对于客户端证书则为证书申请者的姓名; | |
单位名称 (Organization Name):简称:O 字段,对于 SSL 证书,一般为网站域名;而对于代码签名证书则为申请单位名称;而对于客户端单位证书则为证书申请者所在单位名称; | |
证书申请单位所在地: | |
所在城市 (Locality) 简称:L 字段;所在省份 (State/Provice) 简称:S 字段;所在国家 (Country) 简称:C 字段,只能是国家字母缩写,如中国:CN; | |
其他一些字段:电子邮件 (Email) 简称:E 字段;多个姓名字段 简称:G 字段;介绍:Description 字段;电话号码:Phone 字段,格式要求 + 国家区号 城市区号 电话号码,如:+86 732 88888888;地址:STREET 字段;邮政编码:PostalCode 字段;显示其他内容 简称:OU 字段。 |
四 SM2国密算法证书解析
1 数字证书的组成
1)证书数据结构
数字证书使用ASN.1编码,证书文件以二进制或Base64格式存放,数据格式使用TLV(Tag Length Value)形式,T代表类型标识符,L是长度值标识符,V代表值编码。数字证书中的每一项都有个对应的类型T。一个数字证书就是一个大的TLV序列,然后V又由多个TLV组合而成。
SM2证书数据和RSA算法证书一样,包含证书版本、序列号、颁发者、使用者主体信息、使用者公钥、有效期、证书扩展项等,只不过SM2证书的公钥算法是使用ECC算法的Oid标识(1.2.840.10045.2.1),然后公钥参数使用SM2国密算法的Oid标识(1.2.156.10197.1.301)。
2)签名算法
SM2 证书配套的签名算法是基于 SM3 的 SM2 签名算法,算法 Oid 标识为1.2.156.10197.1.501,另外 SM2 国密算法还定义基于SHA_1、SHA_256的签名,以及使用 SM3 算法的 RSA 的签名,只不过签名算法 Oid 标识不一样。
3)签名数据
SM2的签名数据由2个 Big Integer 大数组成,再使用 Der 编码存放签名数据。证书的签名数据由根证书私钥进行签名,使用根证书公钥验证,顶级根证书使用自己的证书公钥验证。
2 数字证书的对象标识符
数字证书的每项都有对象标识Oid,SM2数字证书的主要区别就是公钥算法、公钥参数、签名算法标识不一样,其余的都是X509里标准项。数字证书常见得对象标识有如下:
对象标识符 | 名称 | OID |
---|---|---|
rsaEncryption | RSA算法标识 | 1.2.840.113549.1.1.1 |
sha1withRSAEncryption | SHA1的RSA签名 | 1.2.840.113549.1.1.5 |
ECC | ECC算法标识 | 1.2.840.10045.2.1 |
SM2 | SM2算法标识 | 1.2.156.10197.1.301 |
SM3WithSM2 | SM3的SM2签名 | 1.2.156.10197.1.501 |
sha1withSM2 | SHA1的SM2签名 | 1.2.156.10197.1.502 |
sha256withSM2 | SHA256的SM2签名 | 1.2.156.10197.1.503 |
sm3withRSAEncryption | SM3的RSA签名 | 1.2.156.10197.1.504 |
commonName | 主体名 | 2.5.4.3 |
emailAddress | 邮箱 | 1.2.840.113549.1.9.1 |
cRLDistributionPoints | CRL分发点 | 2.5.29.31 |
extKeyUsage | 扩展密钥用法 | 2.5.29.37 |
subjectAltName | 使用者备用名称 | 2.5.29.17 |
CP | 证书策略 | 2.5.29.32 |
clientAuth | 客户端认证 | 1.3.6.1.5.5.7.3.2 |
3 数字证书的解析
数字证书的解析主要是根据ASN.1语法和对象标识符来获取值,然后再是证书的有效期、颁发机构根证书、CRL吊销状态和使用目的等验证。RSA 证书是标准算法大部分平台都可以解析,而 SM2 国密算法证书的解析就不是那么通用的。在Windows的一些较高版本打开 SM2 证书会显示“验证信任关系时,系统层上出现了一个错误”,这是因为Windows还不支持 SM2 算法证书验证,不能识别 SM2 签名的算法标识,因此需要自行验证SM2证书的签名数据,可基于 BouncyCastle 开源加密库来实现SM2验证签名,详细参见我的国密算法 SM2 证书制作。
五 证书
1 der pem cer crt key pfx等概念及区别
证书主要的文件类型和协议有: PEM、DER、PFX、JKS、KDB、CER、KEY、CSR、CRT、CRL 、OCSP、SCEP等。
一、编码格式
X.509 - 这是一种证书标准,主要定义了证书中应该包含哪些内容。其详情可以参考RFC5280,SSL使用的就是这种证书标准。
目前有以下两种编码格式。
1、PEM - Privacy Enhanced Mail
打开看文本格式,以 -----BEGIN...
开头,-----END...
结尾,内容是 BASE64
编码。查看PEM格式证书的信息:openssl x509 -in certificate.pem -text -noout
;Apache 和 NGINX 服务器偏向于使用这种编码格式。
Openssl 使用 PEM 格式来存放各种信息,它是 openssl 默认采用的信息存放方式。Openssl 中的 PEM 文件一般包含如下信息:
内容类型:表明本文件存放的是什么信息内容,它的形式为 ——-BEGIN XXXX ——
,与结尾的 ——END XXXX——
对应。
头信息:表明数据是如果被处理后存放,openssl 中用的最多的是加密信息,比如加密算法以及初始化向量 iv。
信息体:为 BASE64 编码的数据。可以包括所有私钥(RSA 和 DSA)、公钥(RSA 和 DSA)和 (x509) 证书。它存储用 Base64 编码的 DER 格式数据,用 ascii 报头包围,因此适合系统之间的文本模式传输。
使用PEM格式存储的证书:
—–BEGIN CERTIFICATE—–
MIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx
………
1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=
—–END CERTIFICATE—–
使用PEM格式存储的私钥:
—–BEGIN RSA PRIVATE KEY—–
MIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx
………
1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=
—–END RSA PRIVATE KEY—–
使用PEM格式存储的证书请求文件:
—–BEGIN CERTIFICATE REQUEST—–
MIICJjCCAdCgAwIBAgIBITANBgkqhkiG9w0BAQQFADCBqTELMAkGA1UEBhMCVVMx
………
1p8h5vkHVbMu1frD1UgGnPlOO/K7Ig/KrsU=
—–END CERTIFICATE REQUEST—–
2、DER(Distinguished Encoding Rules) – 辨别编码规则 (DER)
可包含所有私钥、公钥和证书。它是大多数浏览器的缺省格式,并按 ASN1 DER 格式存储。它是无报头的 - PEM 是用文本报头包围的 DER。
DER 打开看是二进制格式,不可读。查看DER格式证书的信息:openssl x509 -in certificate.der -inform der -text -noout
。
Java和Windows服务器偏向于使用这种编码格式。
证书编码的转换
PEM转为DER:openssl x509 -in cert.crt -outform der -out cert.der
;
DER转为PEM:openssl x509 -in cert.crt -inform der -outform pem -out cert.pem
。
(提示:要转换KEY文件也类似,只不过把x509换成rsa,要转CSR的话,把x509换成req…)
二、相关的文件扩展名
这是比较误导人的地方,虽然我们已经知道有 PEM 和 DER 这两种编码格式,但文件扩展名并不一定就叫 “PEM” 或者 “DER”,常见的扩展名除了 PEM 和 DER 还有以下这些,它们除了编码格式可能不同之外,内容也有差别,但大多数都能相互转换编码格式。
CRT - CRT应该是 certificate 的三个字母,其实还是证书的意思,常见于 UNIX 系统,有可能是 PEM 编码,也有可能是 DER 编码,大多数应该是 PEM 编码,相信你已经知道怎么辨别;
CER - 还是 certificate,还是证书,常见于Windows系统,同样的,可能是 PEM 编码,也可能是 DER 编码,大多数应该是 DER 编码。证书中没有私钥,DER 编码二进制格式的证书文件;
KEY - 通常用来存放一个公钥或者私钥,并非 X.509 证书,编码同样的,可能是 PEM,也可能是 DER。查看KEY的办法:openssl rsa -in mykey.key -text -noout
,如果是 DER 格式的话,同理应该这样了:openssl rsa -in mykey.key -text -noout -inform der
;
CSR - Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,其核心内容是一个公钥(当然还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥,私钥要自己保管好。做过iOS APP的朋友都应该知道是怎么向苹果申请开发者证书的吧。查看的办法:openssl req -noout -text -in my.csr
(如果是DER格式的话照旧加上 -inform der
,这里不写了)。
PFX/P12 - predecessor of PKCS#12,包含公钥和私钥的二进制格式证书,对 nginx 服务器来说,一般 CRT 和 KEY 是分开存放在不同文件中的,但 Windows 的 IIS 则将它们存在一个 PFX 文件中,(因此这个文件包含了证书及私钥)这样会不会不安全?应该不会, PFX 通常会有一个"提取密码",你想把里面的东西读取出来的话,它就要求你提供提取密码,PFX 使用的是 DER 编码,如何把 PFX 转换为 PEM 编码?openssl pkcs12 -in for-iis.pfx -out for-iis.pem -nodes
;这个时候会提示你输入提取代码。for-iis.pem
就是可读的文本。
p7b - 以树状展示证书链(certificate chain),同时也支持单个证书,不含私钥。
JKS - 即 Java Key Storage,这是 Java 的专利,跟 OpenSSL 关系不大,利用 Java 的一个叫 “keytool” 的工具,可以将 PFX 转为 JKS,当然了,keytool 也能直接生成 JKS,不过在此就不多表了。
2 .NET中,X509证书2和X509证书有什么区别
该 X509 证书(相对的)限制在其功能是在 .NET 1.0 / 1.1 引入并且是。它可用于获取有关现有证书的信息(有效日期,发行人等)。它有简单的方法/操作(即从磁盘读取证书)。
该 x509Certificate2 是 X509 证书的具有附加功能的一个子类。
它代表一个实际的X509证书。
它在 .NET Framework v2.0 中是新的。
此类可访问所有 V2 和 V3 属性(权限密钥标识符和密钥用法)。
它支持从证书存储装载证书。
除了 X509Certificate 类之外,该框架的1.1版本几乎没有任何其他功能允许您操作证书。事实上,v1.1 X509Certificate 类只提供了基本的支持:它只允许访问 X509 版本1字段(如有效日期和有效日期,主题和公共密钥),而不是版本2字段(如权限密钥标识符)和版本3字段(如密钥用法)。没有支持从证书存储中加载证书,也没有支持访问证书撤销列表或证书信任列表的功能。微软利用Web服务增强(WSE)工具箱扩展了证书类并提供了访问证书存储的类,从而改进了这一点。这些类现在可以在.NET 3.0 / 2.0框架库中找到。
第一个重大变化是从X509Certificate派生出的一个名为 X509Certificate2 的新类。访问 X509 证书字段的方法已被弃用,现在该类具有访问这些字段的属性。另外,如果证书有一个相关的私钥,那么这个类就可以访问这个密钥。有些方法允许您在私钥被一个私钥保护的情况下提供密码。密码通过 SecureString 参数传递,该参数是一种特殊类型,它确保当对象不再使用时,它所占用的内存将被覆盖,以便机器上的另一个进程无法读取密码。下一节将介绍安全字符串和其他形式的受保护数据。
由于 X509Certificate2 派生自 X509Certificate,这意味着您可以通过 X509Certificate2 类调用静态方法 CreateFromeCertFile 和 CreateFromSignedFile。但是,这些方法会返回一个 X509Certificate 对象,并且无法将其转换为 X509Certificate2 对象。X509Certificate 类在版本 3.0 / 2.0 中得到了改进:它提供了访问某些 X509 字段的属性; 它提供了导入和导出方法以从字节数组初始化对象或从证书生成一个字节数组,并且它具有构造函数,它们将从文件(ASN.1 DER)和字节数组中创建一个对象。有趣的是,X509Certificate2 类有一个构造函数,可以从 X509Certificate 对象创建一个 X509Certificate2 对象。
3 Linux中怎么把证书从.pfx转换成.crt和.key?
备注实例:
1、从pfx导出crt和key
.pfx
证书是由 Public Key Cryptography Standards #12 (公钥加密技术12号标准) 定义,包含了公钥和私钥的二进制形式的证书,以 .pfx
作为证书文件的后缀名。
操作命令:
openssl pkcs12 -in example.cn.ssl.pfx -nocerts -nodes -out example.key
openssl pkcs12 -in example.cn.ssl.pfx -clcerts -nokeys -out example.crt
2、将crt和key合并出pfx
操作命令:
openssl pkcs12 -export -in certificate.crt -inkey privateKey.key -out certificate.pfx
3、将.pfx格式的证书转换为.pem文件格式
openssl pkcs12 -in xxx.pfx -nodes -out server.pem
显示结果:
4、从.pem文件中导出私钥server.key
openssl rsa -in server.pem -out server.key
显示结果:
5、从.pem文件中导出证书server.crt
openssl x509 -in server.pem -out server.crt
显示结果:
六 http协议
1 ws协议与http协议的异同
相同:建立在TCP之上,同http一样通过TCP来传输数据;
不同:HTTP协议为单向协议,即浏览器只能向服务器请求资源,服务器才能将数据传送给浏览器,而服务器不能主动向浏览器传递数据。分为长连接和短连接,短连接是每次http请求时都需要三次握手才能发送自己的请求,每个request对应一个response;长连接是短时间内保持连接,保持TCP不断开,指的是TCP连接。
WebSocket解决客户端发起多个http请求到服务器资源浏览器必须要经过长时间的轮询问题。
一种双向通信协议,在建立连接后,WebSocket服务器和Browser/UA都能主动的向对方发送或接收数据,就像Socket一样,不同的是WebSocket是一种建立在Web基础上的一种简单模拟Socket的协议;
WebSocket需要通过握手连接,类似于TCP它也需要客户端和服务器端进行握手连接,连接成功后才能相互通信。
WebSocket在建立握手连接时,数据是通过http协议传输的,“GET/chat HTTP/1.1”,这里面用到的只是http协议一些简单的字段。但是在建立连接之后,真正的数据传输阶段是不需要http协议参与的。
下面是我们访问一个网页,各种协议在里面起的作用。
2 http/https与ws/wss
今天在域名升级到HTTPS的时候遇到websocket的链接问题,之前在http下使用的是new WebSocket(‘ws://xxx’);但是在切换到HTTPS后这个链接部分浏览器报错甚至代码整体抛出异常走不下去了,之前没有注意过websocket在两个不同协议下有什么不同,实际上按照标准来是有如下对应关系的:http -> new WebSocket('ws://xxx')
,https -> new WebSocket('wss://xxx')
;
也就是在https下应该使用wss协议做安全链接,且wss下不支持ip地址的写法,写成域名形式;
经过测试,部分报错的浏览器的确是因为这个原因导致的代码异常,即在https下把ws换成wss请求即可,看到这里心细的也许会发现,是部分浏览器,实际上浏览器并没有严格的限制http下一定使用ws,而不能使用wss,经过测试http协议下同样可以使用wss协议链接,https下同样也能使用ws链接,那么出问题的是哪一部分呢?
1、Firefox环境下https不能使用ws连接;
2、chrome内核版本号低于50的浏览器是不允许https下使用ws链接;
3、Firefox环境下https下使用wss链接需要安装证书;
实际上主要是问题出在Firefox以及低版本的Chrome内核浏览器上,于是在http与https两种协议都支持的情况下可以做兼容处理,即在http协议下使用ws,在https协议下使用wss。
let protocol = location.protocol === 'https:'
? 'wss://localhost:8888'
: 'ws://localhost:8889';
new WebSocket(protocol);
这样可以更加不同的协议环境采取不同的链接方法,当然如果只支持https那最好还是使用wss协议,避免Firefox以及部分低版本Chrome内核浏览器的异常,当然新版本的浏览器都是支持的。
七 OpenSSL库
1 OpenSSL error: storage size of ‘ctx’ isn’t known
OpenSSL版本:OpenSSL 1.1.0g 2 Nov 2017
版本查看命令:openssl version
出现错误代码:
EVP_CIPHER_CTX ctx;
出现错误情况:
error: storage size of ‘ctx’ isn’t known
EVP_CIPHER_CTX ctx;
原因:由于版本更新,接口出现变化,EVP_CIPHER_CTX ctx;
不会做任何事情,所有调用接口过程如下:
EVP_CIPHER_CTX *ctx;
ctx=EVP_CIPHER_CTX_new();
...
EVP_CIPHER_CTX_free(ctx);