5.数字签名

由于发送者和接收者使用相同的共享密码,所以消息认证码无法防止否认。

数字签名——digital signature,也称 电子签名 ,或简称 签名 (signature)。

数字签名技术中,出现了下面两种行为:

在数字签名中,生成签名和验证签名这两个行为需要使用各自专用的密钥来完成。

数字签名对签名密钥和验证密钥进行了区分,使用验证密钥是无法生成签名的。

签名密钥只能由签名的人持有,而验证密钥则是任何需要验证签名的人都可以持有。

autograph——签名,一般指用笔签上自己的名字。

signature——带有签署之意的签名。

公钥密码与数字签名的结构非常相似,实际上, 数字签名 是通过将公钥密码【反过来用】而实现的。

公钥密码与数字签名的密钥使用方式:

 私钥公钥
公钥密码接收者解密时使用发送者加密时使用
数字签名签名者生成签名时使用验证者验证签名时使用
谁持有密钥个人持有只要需要,任何人都可以持有

5.数字签名公钥密码与数字签名数字签名的方法直接对消息签名对消息的散列值签名对数字签名的疑问数字签名的应用实例通过RSA实现数字签名其他数字签名ElGamal方式DSAECDSARabin方式对数字签名的攻击中间人攻击对单向散列函数的攻击利用数字签名攻击公钥密码潜在伪造其他攻击各种密码技术的对比数字签名无法解决的问题

公钥密码与数字签名

公钥密码包括一个由公钥和私钥组成密钥对。公钥用于加密,私钥用于解密。

数字签名中也同样会使用公钥和私钥组成的密钥对,但这两个密钥的用法和公钥密码是相反的。即, 用私钥加密 相当于 生成签名用公钥解密 则相当于 验证签名

组成密钥对的两个密钥之间存在严密的数学关系,它们是一对无法拆散的伙伴。

用私钥进行加密这一行为只能由持有私钥的人完成,于是可以将用私钥加密的文件作为签名来对待。

数字签名的方法

直接对消息签名

发送者事先生成一个包括公钥和私钥的密钥对,并将公钥发送给接收者。

此方法需要对整个消息进行加密,非常耗时(公钥密码算法本来就非常慢)。

  1. 发送者用自己的私钥对消息进行加密

    只有发送者才有私钥,其他人无法生成相同的签名(密文)。

  2. 发送者将消息和签名发送给接收者

  3. 接收者用发送者的公钥对收到的签名进行解密

    如果收到的签名确实是用发送者的私钥进行加密得到的密文(签名),那么发送者的公钥应该能够正确解密。反之则不能正确解密。

  4. 接收者将签名解密后得到的消息与发送者直接发送的消息进行对比

    如果两个一致,则签名验证成功。否则签名验证失败。

对消息的散列值签名

  1. 发送者用单向散列函数计算消息的散列值
  2. 发送者用自己的私钥对散列值进行机密
  3. 发送者将消息和签名发送给接收者
  4. 接收者用发送者的公钥对收到的签名进行解密
  5. 接收者将签名解密后得到的散列值与发送者直接发送的消息的散列值进行对比

对数字签名的疑问

数字签名的应用实例

通过RSA实现数字签名

用RSA生成签名的过程可用下列公式描述:

签名 = 消息D mod N (用RSA生成签名)

此处使用的 DN 就是签名者的私钥。签名就是对消息的 D 次方求 mod N 的结果,也就是说将消息和自己相乘 D 次,然后再除以 N 求余数,最后求得的余数就是签名。

RSA的签名验证过程可用下列公式来表述:

由签名求得的消息 = 签名 E mod N (用RSA验证签名)

这里所设用的 EN 就是签名者的公钥。接收者计算签名的 E 次方并求 mod N ,得到【由签名求得的消息】,并将其与发送者直接发过来的消息内容进行对比。如果两者一致则签名验证成功,否则签名验证失败。

实例:

假设生成了以下密钥对:

公钥: E = 5 ; N = 323

私钥: D =29;N = 323

由于N 为323,因此消息需要为 0~322 这个范围内的整数。假设需要进行签名的消息为 123。

下面用私钥 (DN)=(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)

这两个数字。

接收者收到的以上内容后,使用公钥(EN)= (5,323)来计算由签名求得的消息。

签名E mod N = 1575 mod 323 =123

得到的消息123与发送者直接发过来的消息是一致的,因此签名验证成功。

其他数字签名

ElGamal方式

由Taher ElGamal设计的公钥算法,利用了在 mod N 中求离散对数的困难度。

由于1.0.2版本中数字签名的实现上存在漏洞,因此在GnuPG中的ElGamal仅被用于公钥密码。

DSA

Digital Signature Algorithm,由 NIST——National Institute of Standards and Technology 于1991年制定的数字签名规范(DSS)。

DSA是Schnorr算法于ElGammal方式的变体,只能被用于数字签名。

ECDSA

Elliptic Curve Digital Signature Algorithm,是一种利用椭圆曲线密码来实现的数字签名算法。

Rabin方式

利用 mod N 中求平方根的困难度。可以被用于公钥密码和数字签名。

对数字签名的攻击

中间人攻击

针对公钥密码的中间人攻击对数字签名也颇具威胁。

具体来说就是主动攻击者介入发送者和接收者之间,对发送者伪装成接收者、对接收者伪装成发送者,从而在无需破解数字签名算法的前提下完成攻击。

涉及公钥密码的软件都可以显示公钥的散列值,这个散列值被称为 指纹 (fingerprint)。

对单向散列函数的攻击

数字签名中所使用的单向散列函数必须具有抗碰撞性。

利用数字签名攻击公钥密码

绝对不要对意思不清楚的消息进行签名,因为签名操作实际上可能是对密文的解密操作。

潜在伪造

如果一个没有私钥的攻击者能够对有意义的消息生成合法的数字签名,那么这个数字签名算法一定是不安全的,这样的签名是可以被伪造的。

RSA用于解密的算法中,潜在伪造是可能的。RSA-PSS(probabilistic Signature Scheme)是RSA基础上改良的一种签名算法,它不对消息本身进行签名,而是对其散列值进行签名。另外,在计算散列值的时候还要对消息加盐(salt)。

其他攻击

暴力破解或尝试对RSA的N进行质因数分解等。

各种密码技术的对比

对称密码与公钥密码的对比:

 对称密码公钥密码
发送者用共享密钥加密用公钥加密
接收者用共享密钥解密用私钥解密
密钥配送问题存在不存在,但公钥需要另外认证
机密性okok

消息认证码与数字签名的对比:

 消息认证码数字签名
发送者用共享密钥计算MAC值用私钥生成签名
接收者用共享密钥计算MAC值用公钥验证签名
密钥配送问题存在不存在,但公钥需要另外认证
完整性okok
认证ok,仅限通信对象双方ok,可以适用于任何第三方
防止否认不能可以

在混合密码系统中,消息本身是用对称密码加密的,而只有对称密码的密钥是用公钥密码加密的,此时,对称密码的密钥就相当于消息。

另一方面,数字签名中也使用了同样的方法,即,将消息本身输入单向散列函数求散列值,然后再对散列值进行签名,这里的散列值就相当于消息。

对称密码的 密钥是机密性的关键 ;单向散列函数的 散列值是完整性的关键

数字签名无法解决的问题

数字签名可以识别出篡改和伪装,还可以防止否认。

要正确使用数字签名,有一个大前提,那就是用于验证签名的 公钥必须属于真正的发送者

为了确认我们获得的公钥是合法的,我们需要使用 证书 。所谓证书,就是将公钥当作一条消息,由一个可信的第三方对其签名后得到的公钥。

为了对证书上施加的数字签名进行验证,我们必定需要另一个公钥。要构建一个可信的数字签名链条,就需要让公钥以及数字签名技术成为一种社会性的基础设施,即 公钥基础设施 (Public Key Infrastructure——PKI)。