数字签名:
将报文按双方约定的HASH算法计算得到一个固定位数的报文摘要。在数学上保证:只要改动报文中任何一位,重新计算出的报文摘要值就会与原先的值不相符。这样就保证了报文的不可更改性。
将该报文摘要值用发送者的私人密钥加密,然后连同原报文一起发送给接收者,而产生的报文即称数字签名 。
数字证书:
数字证书就是互联网通讯中标志通讯各方身份信息的一系列数据,提供了一种在Internet上验证您身份的方式,其作用类似于司机的驾驶执照或日常生活中的身份证。它是由一个由权威机构-----CA机构,又称为证书授权(Certificate Authority)中心发行的,人们可以在网上用它来识别对方的身份。数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件。最简单的证书包含一个公开密钥、名称以及证书授权中心的数字签名。
数字证书是一段包含用户身份信息、用户公钥信息以及身份验证机构数字签名的数据。身份验证机构的数字签名可以确保证书信息的真实性,用户公钥信息可以保证数字信息传输的完整性,用户的数字签名可以保证数字信息的不可否认性。
数字证书是各类终端实体和最终用户在网上进行信息交流及商务活动的身份证明,在电子交易的各个环节,交易的各方都需验证对方数字证书的有效性,从而解决相互间的信任问题。
数字证书是一个经证书认证中心(CA)数字签名的包含公开密钥拥有者信息以及公开密钥的文件。认证中心(CA)作为权威的、可信赖的、公正的第三方机构,专门负责为各种认证需求提供数字证书服务。认证中心颁发的数字证书均遵循X.509 V3标准。X.509标准在编排公共密钥密码格式方面已被广为接受。X.509证书已应用于许多网络安全,其中包括IPSec(IP安全)、SSL、SET、S/MIME。
网上银行交易中的安全问题
在网上交易中,交易双方互不见面,有两个安全问题是会引起担心的。第一个问题是交易双方身份是否真实,会不会被人假冒。换句话说,就是在网上发送交易信息的主体是否是真实的。第二个问题是有关交易的信息,如对方的银行账号、金额等是否属实,有没有被人篡改过。
在传统交易中,交易者身份的真实性通过各种证件的出示和验证得到检验;交易信息的真实有效性则通过签名盖章来解决。
然而在网上交易中,传统的实物证件的查验和手写的签名盖章都不可能实现。那这两个问题又是怎么解决的呢?有办法。那就是用含有先进科技的数字证书和数字签名。
公钥密码技术保护交易信息的安全
我们还是从网上传递的信息讲起。
两个人在互联网上作交易,保护交易信息的手段有多种,其中最重要的手段是信息加密技术。加了密的信息只有用密钥才能解开,双方可以提前约定密钥,只要密钥妥善保管,只有买卖双方知道,任何其他人破不了密,交易信息的传递就安全。现代的密码技术强度很大,可以充分地保证密码信息的安全。(请读者牢记这一事实,它是数字签名和数字证书存在的基础。)
但是在互联网上,参加交易的人很多,例如银行,要面对成千上万的客户。想要一个一个地与每个客户约定密钥就变得不可能了。为了解决这个问题,一种新型的密码技术——公钥密码技术应运而生。在这种密码技术中,每个通信者拥有一对独特的密钥——公钥和私钥。公钥可以在网上公开,私钥则密不示人,而且是唯一的。
如果某甲要向某乙发送交易信息,就用在网上公开的某乙的公钥来加密信息,送出去,某乙收到加密的信息后可以用自己的私钥来解密。其他人即使截获了加密的信息也无计可施,因为没有某乙的私钥是解不了密的。这样就保证了交易信息的安全。反过来,某乙向某甲发信息的过程可依此类推。
数字签名的原理
利用公钥技术还可以达到另一个目的,就是解决信息的完整性和有效性。
如果某甲用自己的私钥加密交易信息,传给某乙,某乙可以用某甲的公钥来解密信息。这时,这个被加密的交易信息,例如支付的金额,账号等就是完整、有效的,同时也是不可抵赖的。这是因为某甲的私钥是世界唯一的,别人不可能掌握,如果有人篡改了加密信息,某乙将无法解密。那么,从效用上讲,这个用私钥加密交易信息的动作就像为一个文件签名盖章一样,经过“签名”后的信息是完整、有效的,不可篡改,也不可抵赖。当然,实际上的数字签名机制和过程比这要复杂一些。
如果交易信息很长,用私钥去加密信息将花费较长的时间,效率太低,用户无法接受。因此需要使用一种数学算法——哈希算法——先对这段信息作一次数学变换,把这段信息进行压缩,形成了一段短短的“数字摘要”,让数字摘要来“代表”信息本身。可以通过检验数字摘要,借以判断信息本身是否发生了改变。这样,我们才可以构建真正实用的数字签名。
某甲在发信前使用哈希算法求出待发信息的数字摘要,然后用私钥对这个数字摘要进行加密而形成一段信息,这段信息就称为数字签名。某甲将这个数字签名信息附在待发信息后面,一起发送过去。某乙收到信息后,一方面用某甲的公钥对数字签名解密,得到了摘要H;另一方面把收到的信息本身用同样的哈希算法求出另一个摘要H’,可称为摘要的副本。再把H和H’相比较,看看两者是否相同。根据哈希算法的特性,如果两个摘要H和H’完全符合,证明信息是完整的;如果不符合,就说明信息被人篡改了。
由于摘要一般只有128位或160位比特,比信息本身要短千百倍,数字签名的过程一般在一秒钟内即可完成。
由于数字签名具有数学严格性,黑客对交易信息哪怕只改动一个字一个比特,系统都会发现识破。又因为私钥是不可仿造、伪造的,因此从某种意义上说,数字签名比手写签名更严格可靠。2004年国家颁发的《中华人民共和国电子签名法》赋予了电子签名的法律意义,其规定,“可靠的电子签名能够与手写签名、盖章一样,受到法律保护”。
数字证书的原理
说到这,明眼的观众一定会发现一个关键的问题,就是网上公开的公钥必须真实可靠,因为黑客也可以公布一个假的公钥冒充某甲或某乙来引你上钩呀。怎么来保证这个公钥是真的呢?
这时候就要用到数字证书了。我们知道,身份证是由权威机关公安局颁发的,我们相信公安局,因而我们能够通过检验身份证,相信持有某甲身份证的个人就是某甲本人。同样,数字证书也是要由权威的认证机构来颁发。例如,中国金融认证中心就是一个权威可信的认证机构,它为数百万网上银行的用户颁发了数字证书。
那么,数字证书怎样完成网上身份的认证呢?
把数字证书说成是网上身份证,这是一种形象的比喻。实际上,数字证书所证明的是公钥的真实性。
认证中心对用户的身份进行严格的审核后,为用户颁发数字证书。它通过公钥加密技术对用户的公钥信息和用户的身份信息作了数字签名,把用户所宣称的身份信息与公钥绑定在一起。于是,包含有用户个人身份信息、公钥和数字签名的一个特殊的电子文件就形成了数字证书。数字证书可以存储在硬盘里,也可以存储在软盘或USB Key里。
存储数字证书的USB Key
在网上交易中,用户双方要互相验证这个证书,用户相信认证中心的数字签名,也就相信这个公钥是真实的,因而相信公钥的持有者所发来的信息是真实的。虽然看上去数字证书认证过程与传统的身份证认证有很大差别,但从目的和效用上看,两者是一致的。都是证明发送交易信息主体的真实性。
数字证书的认证、数字签名的发生与核验都是由专用的应用软件来自动实现的,速度极快,眨眼间就完成了,用户并不需要费心做什么操作。
数字证书在网上交易中能够保证交易的安全。
刚才我们提到了,黑客利用种种手段,盗取银行客户的密码、账号,进而企图盗窃客户帐户上的资金。如果网上银行业务采用了数字证书和数字签名的安全机制,黑客即使输入了正确的密码、账号也不能够盗走客户帐户里的资金,因为黑客不掌握客户的数字证书,也不能进行数字签名,网上银行系统就会拒绝交易,使黑客最终功亏一篑。
对称加密、非对称加密
让我们通过一个例子开始:我们的主角分别是Alice和Bob。现在假设 Alice 要给 Bob 发送一份文件,文件内容非常机密。 Alice 不希望文件在发送的过程中被人截取而泄密。
这个时候,自然想到的方法就是对文件进行 加密 。当然除了 加密 外,我们还需要让Bob能够解密 。就像Alice 对文件上了锁,为了让Bob能够解开,则 Bob 必须有钥匙来对文件解锁。在信息安全或密码学中,我们将这种钥匙称为密钥 。密钥一般分为两种,对称密钥 与非对称密钥 :
对称密钥很容易理解,如同 Alice 用一把钥匙将文件上锁,而 Bob使用相同的钥匙就可以将文件解锁,即加密使用的密钥与解密使用的密钥是相同的。目前的对称密钥算法有DES、3DES、AES 等,而密钥则一般是一串固定长度的字符。
如下, Bob 和 Alice 事先已经约定,将使用DES算法,并且已经约定好使用的密钥。于是Alice使用这份密钥对文件进行了加密,并发送给Bob。Bob 使用相同的密钥对文件解密即可:
对称密钥算法的安全性还是非常有保障的。拿 DES算法 举例,到目前为止,除了用穷举搜索法对DES算法进行攻击外,还没有发现更有效的办法。而56位长的密钥 的穷举空间为256,这意味着如果一台计算机的速度是每一秒钟检测一百万个密钥,则它搜索完全部密钥就需要将近2285年的时间。而3DES(3次DES操作)、AES算法的 安全性则更高。由此可见,使用对称密钥对文件进行了加密,基本上不用太担心文件可能泄密。
目前大部分的开发语言都有对应的数字加密模块,例如JAVA的JCE模块就可以调用简单的实现加解密。以下是一份JAVA代码例子:
package com.test.chiper; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import sun.misc.BASE64Decoder; import sun.misc.BASE64Encoder; public class TestChiper { private static final BASE64Encoder base64En = new sun.misc.BASE64Encoder(); private static final BASE64Decoder base64De = new sun.misc.BASE64Decoder(); private static String AESKey="1234567890123456"; public static String encrypt(String mText) throws Exception { SecretKeySpec secrekeysp = new SecretKeySpec( AESKey.getBytes(),"AES"); java.security.Key key = (java.security.Key) secrekeysp; Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(javax.crypto.Cipher.ENCRYPT_MODE, key); byte[] b = cipher.doFinal(mText.getBytes()); return base64En.encode(b); } public static String decrypt(String mText) throws Exception { SecretKeySpec secrekeysp = new SecretKeySpec( AESKey.getBytes(),"AES"); java.security.Key key = (java.security.Key) secrekeysp; Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); cipher.init(javax.crypto.Cipher.DECRYPT_MODE, key); byte[] b = cipher.doFinal(base64De.decodeBuffer(mText)); return new String(b); } }
前文提到的对称密钥算法,已经基本满足了 Alice 对于文件 机密性的要求。然而还是存在两个问题:
1、Alice 与 Bob 彼此之间必须约定将使用的密钥,而这个约定的过程本身就可能存在泄密的风险;
2、如果除了 Alice 以外,还有 Jessica 、 Eva 、 Mary 等 100位女士也需要向Bob发送文件。那么,Bob 可能需要有 100 次约定密钥的过程。
由此可见,无论是安全性还是可用性上,对称密钥都是存在问题的。而两个问题则是必须解决的。
1976 年,美国斯坦福大学的研究生 Diffie 和教授 Hellman 发表一个基于非对称密钥加密的想法,这个想法开创了密码学的变革。他们的想法其实非常简单,将密钥分为 公钥( publicKey ) 和 私钥( privateKey ) 两种。公钥加密的内容,使用私钥可以解开;而私钥加密的内容,公钥可以解开。然而,单独的知道公钥或私钥,却没有办法推出另一份密钥。
继续我们的例子:仍然是Alice 需要与 Bob 发送一份绝密文件。在此之前,Bob生成了一对密钥:公钥和私钥。Bob将公钥发布在了一个公共的密钥库中,而私钥则不对外公开,仅Bob本人持有。如下图所示,Alice从公钥库中取出Bob 的公钥,对文件进行加密,再发送给Bob。而 Bob 通过自己持有的私钥,即可将文件解密:
通过非对称密钥,Bob 只是将公钥公布,并没有和 Alice 约定密钥。仅仅知道公钥是没有办法推出私钥的,因此不用担心私钥泄密的问题。另一反面,如果有jessica也想向Bob发送文件,仅需要从公钥库中取到Bob 的公钥即可,也不需要更多的密钥。
非对称密钥算法很有效的解决了安全性和可用性的问题,非对称密钥算法又称作“公开密钥加密算法”,我们常说的 PKI ( Public Key Infrastructure)则是建立在此技术之上的安全基础体系。目前使用最为广泛的非对称密钥为 RSA算法,该算法是由三位算法发明者的姓氏开头字母命名而来。
由于非对称加密算法的复杂度更高,因此非对称加密的速度远没有对称加密算法快,甚至可能比对称加密慢上 1000 倍。
信息摘要、数字签名
基于上文的非对称密钥算法,我们可以继续我们的场景:
假设有一天, Alice 收到了一份署名为 Bob 的文件。Alice希望能够确认这份文件一定是来自Bob;另外Alice 希望能够确信,这份文件在传输过程中并没有被它人篡改。那么基于非对称密钥算法我们应该怎么做?
确认文件一定来自于 Bob ,其实就是 Bob 无法否认自己发送过这份文件。信息安全中称作不可抵赖性 ;另一方面,确信文件并没有中途被篡改,则称作不可篡改性 。
在非对称密钥算法中提到,公钥加密的内容使用私钥可以解密。同样的,基于私钥加密的内容使用公钥也可以解密,两者一一对应。因此我们可以很容易想到。如果Bob利用自己手里的私钥对文件进行加密后,传输给Alice。Alice再通过公钥库中 Bob的公钥进行解密,则可以证明文件一定是由Bob发出(由于只有Bob持有私钥)。另外,因为传输的是密文,如果能够使用公钥解密,同时也证明了文件并没有中途被篡改。这样的做法其实已经同时满足了不可抵赖性和不可篡改性。
然而,由于传输的文件可能很大,为了证明文件的不可抵赖性和不可篡改性,需要对整个文件进行加密,由于非对称算法效率较低,这样做的代价太大。因此常规的做法是用到信息摘要和数字签名的方式。
所谓信息摘要,其实就是某种 HASH 算法。将信息明文转化为固定长度的字符,它具有如下特点:
① 无论输入的消息有多长,计算出来的消息摘要的长度总是固定的 ;
② 用相同的 摘要算法对相同的消息求两次摘要,其结果必然相同;
③ 一般地,只要输入的消息不同,对其进行摘要以后产生的摘要消息也 几乎不可能相同;
④ 消息摘要函数是单向函数,即只能进行正向的信息摘要,而无法从摘要中恢复出任何的消息 ;
⑤ 好的摘要算法,没有人能从中找到 “ 碰撞 ”,虽然“碰撞” 是肯定存在的。即对于给定的一个摘要,不可能找到一条信息使其摘要正好是给定的。或者说,无法找到两条消息,是它们的摘要相同。
一般的,我们将信息的摘要也称作信息的 指纹 。如同指纹的含义,相同的信息一定会得相同的指纹,而仅通过指纹又无法还原出原始信息。目前主要的摘要算法有MD5 和SHA1 。
当有了信息摘要技术以后,基于 Bob 向 Alice 发送文件的场景,我们可以进行如下的操作:
第一步:
① Bob 将原始的信息进行一次信息摘要算法,得到原始信息的摘要值;
② Bob 使用自己的私钥,对该摘要值进行加密。得到信息摘要的密文;
③ Bob 将原始文件和摘要值的密文一起发送给 Alice 。
④ 一般的,我们将原始文件和摘要密文称作 Bob 对原始文件的签名结果。
第二步:
① 当Alice 接收到 Bob 传输的信息(原始文件,信息摘要密文)后,使用Bob的公钥将摘要密文解密,得到信息摘要明文;
② 使用信息摘要算法,取原文的摘要信息,获取原始文件摘要信息;
③ Alice 比较解密后的摘要信息和取得的摘要信息。如果相同,则可以证明文件一定由 Bob发送,并且中途并没有经过任何篡改。一般将这个过程称作 验签。
所谓数字签名,就是对原始文件的“指纹”进行了私钥加密。这样,即可保证文件的特征(摘要值)一定经过了私钥的加密。同时由于信息摘要的长度普遍不长( MD5 为 128 位, SHA1 主要为 256 位),也并没有带来太大的开销。
如同对称密钥算法,在大部分开发语言中,基于非对称算法的数字签名,数字加密算法。也都进行了一定的封装。如下链接就比较详细的描述了基于 JCE 如何实现数字签名、加密、验证等:
http://blog.youkuaiyun.com/centralperk/article/details/8538697
数字证书
基于非对称密钥算法, Bob 生成了一对公私钥。 Bob将公钥发布在公开的密钥库中。而Alice在向Bob 发送加密文件或者验证 Bob 签名的文件时,均要从公钥库取到Bob的公钥。我们已经知道,一般来说公钥就是一段固定长度的字符串,并没有特定的含义。
为了让 Alice 能够方便的辨别公钥,我们可以考虑对给公钥附加一些信息,例如该公钥使用的算法,该公钥的所有者(主题),该公钥的有效期等一系列属性。这样的数据结构我们称作PKCS10数据包

公钥的 主题 我们采用唯一标示符 ( 或称 DN-distinguished name),以尽量唯一的标示公钥所有者。以下是基于 抽象语法表示法所定义的PKCS10数据结构:
CertificationRequestInfo ::= SEQUENCE { version INTEGER { v1(0) } (v1,...), subject Name, subjectPKInfo SubjectPublicKeyInfo{{ PKInfoAlgorithms }}, attributes [0] Attributes{{ CRIAttributes }} } SubjectPublicKeyInfo { ALGORITHM : IOSet} ::= SEQUENCE { algorithm AlgorithmIdentifier {{IOSet}}, subjectPublicKey BIT STRING } PKInfoAlgorithms ALGORITHM ::= { ... -- add any locally defined algorithms here -- } Attributes { ATTRIBUTE:IOSet } ::= SET OF Attribute{{ IOSet }} CRIAttributes ATTRIBUTE ::= { ... -- add any locally defined attributes here -- } Attribute { ATTRIBUTE:IOSet } ::= SEQUENCE { type ATTRIBUTE.&id({IOSet}), values SET SIZE(1..MAX) OF ATTRIBUTE.&Type({IOSet}{@type}) }
我们已经有了 PKCS10 数据包,除了公钥信息外,还有公钥的持有者,公钥的版本号等信息。然而这样的数据结构其实并没有任何权威性。例如有一天一个叫做Richard的人想冒充Bob,也生成一对公私钥,并且使用了相同的公钥主题封装为P10数据结构。Alice其实并没有办法分辨哪个是真实Bob的公钥。
为了解决这个问题,就需要一个权威的第三方机构,对 P10 结构的数据进行认证。就如同对P10文件盖上一个权威的章,防止仿照。这样的权威机构,我们称作CA(Certificate Authority)数字证书认证中心 。而CA如何为P10数据盖章呢?非常简单,就是我们前文已经提到的数字签名技术:
① 如上图所示,CA 机构其实也持有一张私钥。一般来说, CA 会对这份私钥进行特别的保护,严禁泄漏和盗用。
② Bob 将自己的公钥附加上一系列信息后,形成了 P10 数据包(请求包),并发送给CA。
③ CA 机构通过其他一些手段,例如查看 Bob 的身份信息等方式,认可了Bob的身份。于是使用自己的私钥对P10请求进行签名。(也可能会先对数据进行一些简单修改,如修改有效期或主题等)
④ 这样的签名结果,我们就称作数字证书。
数字证书同样遵循一个格式标准,我们称作X509标准,我们一般提到的 X509 证书就是如此。以下是X509的格式:
[Certificate ::= SEQUENCE { tbsCertificate TBSCertificate, signatureAlgorithm AlgorithmIdentifier, signature BIT STRING } TBSCertificate ::= SEQUENCE { version [0] EXPLICIT Version DEFAULT v1, serialNumber CertificateSerialNumber, signature AlgorithmIdentifier, issuer Name, validity Validity, subject Name, subjectPublicKeyInfo SubjectPublicKeyInfo, issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, -- If present, version must be v2or v3 subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, -- If present, version must be v2or v3 extensions [3] EXPLICIT Extensions OPTIONAL -- If present, version must be v3 } Version ::= INTEGER { v1(0), v2(1), v3(2) } CertificateSerialNumber ::= INTEGER Validity ::= SEQUENCE { notBefore CertificateValidityDate, notAfter CertificateValidityDate } CertificateValidityDate ::= CHOICE { utcTime UTCTime, generalTime GeneralizedTime } UniqueIdentifier ::= BIT STRING SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING } Extensions ::= SEQUENCE OF Extension Extension ::= SEQUENCE { extnID OBJECT IDENTIFIER, critical BOOLEAN DEFAULT FALSE, extnValue OCTET STRING }
基于数字证书,我们可以再来看看 Bob 如何给 Alice发送一份不可否认、不可篡改的文件:
第一步: Bob 除了对文件进行签名操作外,同时附加了自己的数字证书。一同发给 Alice 。
第二步: Alice 首先使用 CA 的公钥,对证书进行验证。如果验证成功,提取证书中的公钥,对Bob发来的文件进行验签。如果验证成功,则证明文件的不可否认和不可篡改。
可以看到,基于数字证书后, Alice 不在需要一个公钥库维护 Bob(或其他人)的公钥证书,只要持有CA的公钥即可。 数字证书在电子商务,电子认证等方面使用非常广泛,就如同计算机世界的身份证,可以证明企业、个人、网站等实体的身份。同时基于数字证书,加密算法的技术也可以支持一些安全交互协议(如SSL)。
参考原文:http://blog.youkuaiyun.com/u014419512/article/details/26290821
加密工作模式
参考原文:http://blog.poxiao.me/p/advanced-encryption-standard-and-block-cipher-mode/