由于发送者和接收者使用相同的共享密码,所以消息认证码无法防止否认。
数字签名——digital signature,也称 电子签名 ,或简称 签名 (signature)。
数字签名技术中,出现了下面两种行为:
生成消息签名的行为
由发送者完成,也称【对消息签名】。根据消息内容计算数字签名的值。
验证消息签名的行为
一般是由接收者完成,但也可以由需要验证消息的第三方完成,这里的第三方被命名为 验证者 Victor 。
在数字签名中,生成签名和验证签名这两个行为需要使用各自专用的密钥来完成。
数字签名对签名密钥和验证密钥进行了区分,使用验证密钥是无法生成签名的。
签名密钥只能由签名的人持有,而验证密钥则是任何需要验证签名的人都可以持有。
autograph——签名,一般指用笔签上自己的名字。
signature——带有签署之意的签名。
公钥密码与数字签名的结构非常相似,实际上, 数字签名 是通过将公钥密码【反过来用】而实现的。
公钥密码与数字签名的密钥使用方式:
私钥 | 公钥 | |
---|---|---|
公钥密码 | 接收者解密时使用 | 发送者加密时使用 |
数字签名 | 签名者生成签名时使用 | 验证者验证签名时使用 |
谁持有密钥 | 个人持有 | 只要需要,任何人都可以持有 |
5.数字签名公钥密码与数字签名数字签名的方法直接对消息签名对消息的散列值签名对数字签名的疑问数字签名的应用实例通过RSA实现数字签名其他数字签名ElGamal方式DSAECDSARabin方式对数字签名的攻击中间人攻击对单向散列函数的攻击利用数字签名攻击公钥密码潜在伪造其他攻击各种密码技术的对比数字签名无法解决的问题
公钥密码包括一个由公钥和私钥组成密钥对。公钥用于加密,私钥用于解密。
数字签名中也同样会使用公钥和私钥组成的密钥对,但这两个密钥的用法和公钥密码是相反的。即, 用私钥加密 相当于 生成签名 , 用公钥解密 则相当于 验证签名 。
组成密钥对的两个密钥之间存在严密的数学关系,它们是一对无法拆散的伙伴。
用私钥进行加密这一行为只能由持有私钥的人完成,于是可以将用私钥加密的文件作为签名来对待。
发送者事先生成一个包括公钥和私钥的密钥对,并将公钥发送给接收者。
此方法需要对整个消息进行加密,非常耗时(公钥密码算法本来就非常慢)。
发送者用自己的私钥对消息进行加密
只有发送者才有私钥,其他人无法生成相同的签名(密文)。
发送者将消息和签名发送给接收者
接收者用发送者的公钥对收到的签名进行解密
如果收到的签名确实是用发送者的私钥进行加密得到的密文(签名),那么发送者的公钥应该能够正确解密。反之则不能正确解密。
接收者将签名解密后得到的消息与发送者直接发送的消息进行对比
如果两个一致,则签名验证成功。否则签名验证失败。
密文为什么能作为签名使用
数字签名是利用了【没有私钥的人事实上无法生成使用该私钥所生成的密文】这一性质来实现的。
此时所生成的密文并非被用于保证机密性,而是被用于代表一种【只有持有该密钥的人才能够生成的信息】。
(大概类似于密码学的【不可否认性】 Non-repudiation )
这样的信息一般称为 认证符号 (authenticator),消息认证码也是一种认证符号,数字签名也是一样。数字签名是通过使用私钥进行加密来产生认证符号的。
数字签名不能保证机密性吗
数字签名的作用本来就不是保证机密性,因此它不会加密消息。如果要保证机密性,应将消息加密后再发送。
数字签名可以被复制吗
签名所表达的意义是, 特定的签名者对特定的消息进行了签名 ,即便签名被复制,也并不会改变签名者和消息的内容。
消息内容会不会被任意修改
签名之后可以对消息和签名进行修改,但修改后验证签名就会失败,进行验证的人就能够发现这一修改行为。
数字签名所要实现的不是【防止】修改,而是【识别】修改。
能否同时修改消息和签名,是的验证签名成功?事实上是做不到的。
以对散列值签名为例,只要消息被修改1比特,重新计算的散列值都会发生很大的变化,要拼凑出合法的签名,必须在不知道私钥的前提下对新的散列值进行加密,事实上是无法做到的。
这个问题相当于对数字签名的攻击。
签名会不会被重放使用
即使将签名部分提取出来,然后附加到别的消息后面,验证签名依然会失败。
签名和消息之间具有对应关系:消息不同,签名内容也不同。因此无法做到提取签名重复使用。
删除签名也无法“作废合同”吗
要作废带有数字签名的借据,可以重新创建一份相当于收据的文书,并让对方在这份文书上加上数字签名。
如何防止否认
防止否认与【谁持有密钥】有密切关系。
在消息认证码中,能够计算MAC值的密钥(共享密钥)是由发送者和接收者双方共同持有的,因此双方都可以计算MAC值,从而无法严格确认MAC值是由哪一方计算的。
在数字签名中,只有拥有私钥的人才能生成签名。除非他说私钥被窃取了。
数字签名真的能够替代签名吗
单纯认为数字签名比普通印章或手写签名更可信,是非常危险的。
发布安全信息公告
公告的目的是尽量让更多人知道,但必须排除有人恶意伪造的风险。因此公告不需加密,而是加上数字签名。
这种对明文消息所施加的签名,一般称为 明文签名 (clearsign)。
软件下载
需要判断所下载的软件是否可以安全运行。软件作者可以对软件加上数字签名。
但数字签名只能检测软件是否被篡改过,并不能保证软件本身不会做出恶意的行为。
公钥证书
在验证数字签名时我们需要合法的公钥。对公钥加上数字签名,就得到公钥证书。
SSL/TLS
加上了数字签名的服务器公钥。
用RSA生成签名的过程可用下列公式描述:
签名 = 消息D mod N (用RSA生成签名)
此处使用的 D 和 N 就是签名者的私钥。签名就是对消息的 D 次方求 mod N 的结果,也就是说将消息和自己相乘 D 次,然后再除以 N 求余数,最后求得的余数就是签名。
RSA的签名验证过程可用下列公式来表述:
由签名求得的消息 = 签名 E mod N (用RSA验证签名)
这里所设用的 E 和 N 就是签名者的公钥。接收者计算签名的 E 次方并求 mod N ,得到【由签名求得的消息】,并将其与发送者直接发过来的消息内容进行对比。如果两者一致则签名验证成功,否则签名验证失败。
实例:
假设生成了以下密钥对:
公钥: E = 5 ; N = 323
私钥: D =29;N = 323
由于N 为323,因此消息需要为 0~322 这个范围内的整数。假设需要进行签名的消息为 123。
下面用私钥 (D ,N)=(29,323)来生成消息123的签名。
消息D mod N = 12329 mod 323 =157
(用python计算: 123**29%323
也可以使用以下方法:
12329 mod 323 = (12310 mod 323)x(12310 mod 323)x(1239 mod 323) mod 323
= 237 x 237 x 191 mod 323
= 10728279 mod 323
= 157
)
签名是157。向接收者发送的内容为:
(消息,签名)= (123,157)
这两个数字。
接收者收到的以上内容后,使用公钥(E ,N)= (5,323)来计算由签名求得的消息。
签名E mod N = 1575 mod 323 =123
得到的消息123与发送者直接发过来的消息是一致的,因此签名验证成功。
由Taher ElGamal设计的公钥算法,利用了在 mod N 中求离散对数的困难度。
由于1.0.2版本中数字签名的实现上存在漏洞,因此在GnuPG中的ElGamal仅被用于公钥密码。
Digital Signature Algorithm,由 NIST——National Institute of Standards and Technology 于1991年制定的数字签名规范(DSS)。
DSA是Schnorr算法于ElGammal方式的变体,只能被用于数字签名。
Elliptic Curve Digital Signature Algorithm,是一种利用椭圆曲线密码来实现的数字签名算法。
利用 mod N 中求平方根的困难度。可以被用于公钥密码和数字签名。
针对公钥密码的中间人攻击对数字签名也颇具威胁。
具体来说就是主动攻击者介入发送者和接收者之间,对发送者伪装成接收者、对接收者伪装成发送者,从而在无需破解数字签名算法的前提下完成攻击。
涉及公钥密码的软件都可以显示公钥的散列值,这个散列值被称为 指纹 (fingerprint)。
数字签名中所使用的单向散列函数必须具有抗碰撞性。
绝对不要对意思不清楚的消息进行签名,因为签名操作实际上可能是对密文的解密操作。
如果一个没有私钥的攻击者能够对有意义的消息生成合法的数字签名,那么这个数字签名算法一定是不安全的,这样的签名是可以被伪造的。
RSA用于解密的算法中,潜在伪造是可能的。RSA-PSS(probabilistic Signature Scheme)是RSA基础上改良的一种签名算法,它不对消息本身进行签名,而是对其散列值进行签名。另外,在计算散列值的时候还要对消息加盐(salt)。
暴力破解或尝试对RSA的N进行质因数分解等。
对称密码与公钥密码的对比:
对称密码 | 公钥密码 | |
---|---|---|
发送者 | 用共享密钥加密 | 用公钥加密 |
接收者 | 用共享密钥解密 | 用私钥解密 |
密钥配送问题 | 存在 | 不存在,但公钥需要另外认证 |
机密性 | ok | ok |
消息认证码与数字签名的对比:
消息认证码 | 数字签名 | |
---|---|---|
发送者 | 用共享密钥计算MAC值 | 用私钥生成签名 |
接收者 | 用共享密钥计算MAC值 | 用公钥验证签名 |
密钥配送问题 | 存在 | 不存在,但公钥需要另外认证 |
完整性 | ok | ok |
认证 | ok,仅限通信对象双方 | ok,可以适用于任何第三方 |
防止否认 | 不能 | 可以 |
在混合密码系统中,消息本身是用对称密码加密的,而只有对称密码的密钥是用公钥密码加密的,此时,对称密码的密钥就相当于消息。
另一方面,数字签名中也使用了同样的方法,即,将消息本身输入单向散列函数求散列值,然后再对散列值进行签名,这里的散列值就相当于消息。
对称密码的 密钥是机密性的关键 ;单向散列函数的 散列值是完整性的关键 。
数字签名可以识别出篡改和伪装,还可以防止否认。
要正确使用数字签名,有一个大前提,那就是用于验证签名的 公钥必须属于真正的发送者 。
为了确认我们获得的公钥是合法的,我们需要使用 证书 。所谓证书,就是将公钥当作一条消息,由一个可信的第三方对其签名后得到的公钥。
为了对证书上施加的数字签名进行验证,我们必定需要另一个公钥。要构建一个可信的数字签名链条,就需要让公钥以及数字签名技术成为一种社会性的基础设施,即 公钥基础设施 (Public Key Infrastructure——PKI)。