zoukankan      html  css  js  c++  java
  • 【转载】公钥、私钥、数字签名等知识

    参考这篇文章,讲得很好:http://www.blogjava.net/yxhxj2006/archive/2012/10/15/389547.html

    来自:http://www.ruanyifeng.com/blog/2011/08/what_is_a_digital_signature.html

    它用图片通俗易懂地解释了,"数字签名"(digital signature)"数字证书"(digital certificate)到底是什么。

    1. 鲍勃有两把钥匙,一把是公钥,另一把是私钥。

    2. 鲍勃把公钥送给他的朋友们----帕蒂、道格、苏珊----每人一把。

    3. 苏珊要给鲍勃写一封保密的信。她写完后用鲍勃的公钥加密,就可以达到保密的效果。

    4. 鲍勃收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要鲍勃的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。

    5. 鲍勃给苏珊回信,决定采用"数字签名"。他写完后先用Hash函数,生成信件的摘要(digest)。

    6. 然后,鲍勃使用私钥,对这个摘要加密,生成"数字签名"(signature)。

    7. 鲍勃将这个签名,附在信件下面,一起发给苏珊。

    8. 苏珊收信后,取下数字签名,用鲍勃的公钥解密,得到信件的摘要。由此证明,这封信确实是鲍勃发出的。

     

    9. 苏珊再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。

    10. 复杂的情况出现了。道格想欺骗苏珊,他偷偷使用了苏珊的电脑,用自己的公钥换走了鲍勃的公钥。此时,苏珊实际拥有的是道格的公钥,但是还以为这是鲍勃的公钥。因此,道格就可以冒充鲍勃,用自己的私钥做成"数字签名",写信给苏珊,让苏珊用假的鲍勃公钥进行解密。

    11. 后来,苏珊感觉不对劲,发现自己无法确定公钥是否真的属于鲍勃。她想到了一个办法,要求鲍勃去找"证书中心"(certificate authority,简称CA),为公钥做认证。证书中心用自己的私钥,对鲍勃的公钥和一些相关信息一起加密,生成"数字证书"(Digital Certificate)。

    12. 鲍勃拿到数字证书以后,就可以放心了。以后再给苏珊写信,只要在签名的同时,再附上数字证书就行了。

    13. 苏珊收信后,用CA的公钥解开数字证书,就可以拿到鲍勃真实的公钥了,然后就能证明"数字签名"是否真的是鲍勃签的。

    14. 下面,我们看一个应用"数字证书"的实例:https协议。这个协议主要用于网页加密。

    15. 首先,客户端向服务器发出加密请求。

    16. 服务器用自己的私钥加密网页以后,连同本身的数字证书,一起发送给客户端。

     17. 客户端(浏览器)的"证书管理器",有"受信任的根证书颁发机构"列表。客户端会根据这张列表,查看解开数字证书的公钥是否在列表之内。

    18. 如果数字证书记载的网址,与你正在浏览的网址不一致,就说明这张证书可能被冒用,浏览器会发出警告。

    19. 如果这张数字证书不是由受信任的机构颁发的,浏览器会发出另一种警告。

    20. 如果数字证书是可靠的,客户端就可以使用证书中的服务器公钥,对信息进行加密,然后与服务器交换加密信息。

    这里有两篇ruanyifeng的rsa原理:

    http://www.ruanyifeng.com/blog/2013/06/rsa_algorithm_part_one.html

    如果你问我,哪一种算法最重要?

    我可能会回答"公钥加密算法"。因为它是计算机通信安全的基石,保证了加密数据不会被破解。你可以想象一下,信用卡交易被破解的后果。

    一、一点历史

    1976年以前,所有的加密方法都是同一种模式:

      (1)甲方选择某一种加密规则,对信息进行加密;

      (2)乙方使用同一种规则,对信息进行解密。

    由于加密和解密使用同样规则(简称"密钥"),这被称为"对称加密算法"(Symmetric-key algorithm)。

    这种加密模式有一个最大弱点:甲方必须把加密规则告诉乙方,否则无法解密。保存和传递密钥,就成了最头疼的问题。

    1976年,两位美国计算机学家Whitfield Diffie 和 Martin Hellman,提出了一种崭新构思,可以在不直接传递密钥的情况下,完成解密。这被称为"Diffie-Hellman密钥交换算法"。这个算法启发了其他科学家。人们认识到,加密和解密可以使用不同的规则,只要这两种规则之间存在某种对应关系即可,这样就避免了直接传递密钥。

    这种新的加密模式被称为"非对称加密算法"。

      (1)乙方生成两把密钥(公钥和私钥)。公钥是公开的,任何人都可以获得,私钥则是保密的。

      (2)甲方获取乙方的公钥,然后用它对信息加密。

      (3)乙方得到加密后的信息,用私钥解密。

    如果公钥加密的信息只有私钥解得开,那么只要私钥不泄漏,通信就是安全的。


    1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。毫不夸张地说,只要有计算机网络的地方,就有RSA算法。

    这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全

    进入正题,解释RSA算法的原理。文章共分成两部分,今天是第一部分,介绍要用到的四个数学概念。你可以看到,RSA算法并不难,只需要一点数论知识就可以理解。

    二、互质关系

    如果两个正整数,除了1以外,没有其他公因子,我们就称这两个数是互质关系(coprime)。比如,15和32没有公因子,所以它们是互质关系。这说明,不是质数也可以构成互质关系。

    关于互质关系,不难得到以下结论:

      1. 任意两个质数构成互质关系,比如13和61。
      2. 一个数是质数,另一个数只要不是前者的倍数,两者就构成互质关系,比如3和10。
      3. 如果两个数之中,较大的那个数是质数,则两者构成互质关系,比如97和57。
      4. 1和任意一个自然数是都是互质关系,比如1和99。
      5. p是大于1的整数,则p和p-1构成互质关系,比如57和56。
      6. p是大于1的奇数,则p和p-2构成互质关系,比如17和15。

    三、欧拉函数

    任意给定正整数n,请问在小于等于n的正整数之中,有多少个与n构成互质关系?(比如,在1到8之中,有多少个数与8构成互质关系?)

    计算这个值的方法就叫做欧拉函数,以φ(n)表示。在1到8之中,与8形成互质关系的是1、3、5、7,所以 φ(n) = 4。

    四、欧拉定理

    欧拉函数的用处,在于欧拉定理。"欧拉定理"指的是

    如果两个正整数a和n互质,则n的欧拉函数 φ(n) 可以让下面的等式成立:

    欧拉定理的证明比较复杂,这里就省略了。我们只要记住它的结论就行了。

    欧拉定理可以大大简化某些运算。比如,7和10互质,根据欧拉定理,

    已知 φ(10) 等于4,所以马上得到7的4倍数次方的个位数肯定是1。

    因此,7的任意次方的个位数(例如7的222次方),心算就可以算出来。

    欧拉定理有一个特殊情况。

    假设正整数a与质数p互质,因为质数p的φ(p)等于p-1,则欧拉定理可以写成

    这就是著名的费马小定理。它是欧拉定理的特例。

    欧拉定理是RSA算法的核心。理解了这个定理,就可以理解RSA。

    五、模反元素

    还剩下最后一个概念:

    如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除,或者说ab被n除的余数是1。

    这时,b就叫做a的"模反元素"

    欧拉定理可以用来证明模反元素必然存在。

    可以看到,a的 φ(n)-1 次方,就是a的模反元素。

    下面到第二篇,如下: 

    http://www.ruanyifeng.com/blog/2013/07/rsa_algorithm_part_two.html

    有了上面第一篇的这些知识,我们就可以看懂RSA算法。这是目前地球上最重要的加密算法。

    六、密钥生成的步骤

    我们通过一个例子,来理解RSA算法。假设爱丽丝要与鲍勃进行加密通信,她该怎么生成公钥和私钥呢?

    (下图好像反了)

    第一步,随机选择两个不相等的质数p和q。

    爱丽丝选择了61和53。(实际应用中,这两个质数越大,就越难破解。)

    第二步,计算p和q的乘积n。

    爱丽丝就把61和53相乘。

      n = 61×53 = 3233

    n的长度就是密钥长度。3233写成二进制是110010100001,一共有12位,所以这个密钥就是12位。实际应用中,RSA密钥一般是1024位,重要场合则为2048位。

    第三步,计算n的欧拉函数φ(n)。

    根据公式:

      φ(n) = (p-1)(q-1)

    爱丽丝算出φ(3233)等于60×52,即3120。

    第四步,随机选择一个整数e,条件是1< e < φ(n),且e与φ(n) 互质。

    爱丽丝就在1到3120之间,随机选择了17。(实际应用中,常常选择65537。)

    第五步,计算e对于φ(n)的模反元素d。

    所谓"模反元素"就是指有一个整数d,可以使得ed被φ(n)除的余数为1。

      ed ≡ 1 (mod φ(n))

    这个式子等价于

      ed - 1 = kφ(n)

    于是,找到模反元素d,实质上就是对下面这个二元一次方程求解。

      ex + φ(n)y = 1

    已知 e=17, φ(n)=3120,

      17x + 3120y = 1

    这个方程可以用"扩展欧几里得算法"求解,此处省略具体过程。总之,爱丽丝算出一组整数解为 (x,y)=(2753,-15),即 d=2753。

    至此所有计算完成。

    第六步,将n和e封装成公钥,n和d封装成私钥。

    在爱丽丝的例子中,n=3233,e=17,d=2753,所以公钥就是 (3233,17),私钥就是(3233, 2753)。

    实际应用中,公钥和私钥的数据都采用ASN.1格式表达

    七、RSA算法的可靠性

    回顾上面的密钥生成步骤,一共出现六个数字:

      p
      q
      n
      φ(n)
      e
      d

    这六个数字之中,公钥用到了两个(n和e),其余四个数字都是不公开的。其中最关键的是d,因为n和d组成了私钥,一旦d泄漏,就等于私钥泄漏。

    那么,有无可能在已知n和e的情况下,推导出d?

      (1)ed≡1 (mod φ(n))。只有知道e和φ(n),才能算出d。

      (2)φ(n)=(p-1)(q-1)。只有知道p和q,才能算出φ(n)。

      (3)n=pq。只有将n因数分解,才能算出p和q。

    结论:如果n可以被因数分解,d就可以算出,也就意味着私钥被破解。

    可是,大整数的因数分解,是一件非常困难的事情。目前,除了暴力破解,还没有发现别的有效方法。

    维基百科这样写道:

      "对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。

      假如有人找到一种快速因数分解的算法,那么RSA的可靠性就会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA密钥才可能被暴力破解。到2008年为止,世界上还没有任何可靠的攻击RSA算法的方式。

      只要密钥长度足够长,用RSA加密的信息实际上是不能被解破的。"

    举例来说,你可以对3233进行因数分解(61×53),但是你没法对下面这个整数进行因数分解。

      12301866845301177551304949
      58384962720772853569595334
      79219732245215172640050726
      36575187452021997864693899
      56474942774063845925192557
      32630345373154826850791702
      61221429134616704292143116
      02221240479274737794080665
      351419597459856902143413

    它等于这样两个质数的乘积:

      33478071698956898786044169
      84821269081770479498371376
      85689124313889828837938780
      02287614711652531743087737
      814467999489
        ×
      36746043666799590428244633
      79962795263227915816434308
      76426760322838157396665112
      79233373417143396810270092
      798736308917

    事实上,这大概是人类已经分解的最大整数(232个十进制位,768个二进制位)。比它更大的因数分解,还没有被报道过,因此目前被破解的最长RSA密钥就是768位。

    八、加密和解密

    有了公钥和密钥,就能进行加密和解密了。

    (1)加密要用公钥 (n,e)

    假设鲍勃要向爱丽丝发送加密信息m,他就要用爱丽丝的公钥 (n,e) 对m进行加密。这里需要注意,m必须是整数(字符串可以取ascii值或unicode值),且m必须小于n。

    所谓"加密",就是算出下式的c:

      me ≡ c (mod n)

    爱丽丝的公钥是 (3233, 17),鲍勃的m假设是65,那么可以算出下面的等式:

      6517 ≡ 2790 (mod 3233)

    于是,c等于2790,鲍勃就把2790发给了爱丽丝。

    (2)解密要用私钥(n,d)

    爱丽丝拿到鲍勃发来的2790以后,就用自己的私钥(3233, 2753) 进行解密。可以证明,下面的等式一定成立:

      cd ≡ m (mod n)

    也就是说,c的d次方除以n的余数为m。现在,c等于2790,私钥是(3233, 2753),那么,爱丽丝算出

      27902753 ≡ 65 (mod 3233)

    因此,爱丽丝知道了鲍勃加密前的原文就是65。

    至此,"加密--解密"的整个过程全部完成。

    我们可以看到,如果不知道d,就没有办法从c求出m。而前面已经说过,要知道d就必须分解n,这是极难做到的,所以RSA算法保证了通信安全。

    你可能会问,公钥(n,e) 只能加密小于n的整数m,那么如果要加密大于n的整数,该怎么办?有两种解决方法:一种是把长信息分割成若干段短消息,每段分别加密;另一种是先选择一种"对称性加密算法"(比如DES,用这种算法的密钥加密信息,再用RSA公钥加密DES密钥。

    那么是不是私钥加密,公钥也能解密呢,这里讲的很清楚:https://www.zhihu.com/question/25912483/answer/31653639

    =================分割线=================

    我们来回顾一下RSA的加密算法。我们从公钥加密算法和签名算法的定义出发,用比较规范的语言来描述这一算法。

    RSA公钥加密体制包含如下3个算法:KeyGen(密钥生成算法),Encrypt(加密算法)以及Decrypt(解密算法)。

    • (PK, SK)leftarrow KeyGen(lambda)。密钥生成算法以安全常数lambda作为输入,输出一个公钥PK,和一个私钥SK。安全常数用于确定这个加密算法的安全性有多高,一般以加密算法使用的质数p的大小有关。lambda越大,质数p一般越大,保证体制有更高的安全性。在RSA中,密钥生成算法如下:算法首先随机产生两个不同大质数p和q,计算N=pq。随后,算法计算欧拉函数varphi(N)=(p-1)(q-1)。接下来,算法随机选择一个小于varphi(N)的整数e,并计算e关于varphi(N)的模反元素d。最后,公钥为PK=(N, e),私钥为SK=(N, d)。
    • CT leftarrow Encrypt(PK,M)。加密算法以公钥PK和待加密的消息M作为输入,输出密文CT。在RSA中,加密算法如下:算法直接输出密文为CT=M^e mod N
    • M leftarrow Decrypt(SK,CT)。解密算法以私钥SK和密文CT作为输入,输出消息M。在RSA中,解密算法如下:算法直接输出明文为M=CT^d mod N。由于e和d在varphi(N)下互逆,因此我们有:CT^d=M^{ed}=M mod N

    所以,从算法描述中我们也可以看出:公钥用于对数据进行加密,私钥用于对数据进行解密。当然了,这个也可以很直观的理解:公钥就是公开的密钥,其公开了大家才能用它来加密数据。私钥是私有的密钥,谁有这个密钥才能够解密密文。否则大家都能看到私钥,就都能解密,那不就乱套了。


    =================分割线=================

    我们再来回顾一下RSA签名体制。签名体制同样包含3个算法:KeyGen(密钥生成算法),Sign(签名算法),Verify(验证算法)。

    • (PK,SK) leftarrow KeyGen(lambda)。密钥生成算法同样以安全常数lambda作为输入,输出一个公钥PK和一个私钥SK。在RSA签名中,密钥生成算法与加密算法完全相同。
    • sigma leftarrow Sign(SK,M)。签名算法以私钥SK和待签名的消息M作为输入,输出签名sigma。在RSA签名中,签名算法直接输出签名为sigma = M^d mod N。注意,签名算法和RSA加密体制中的解密算法非常像
    • b leftarrow Verify(PK,sigma,M)。验证算法以公钥PK,签名sigma以及消息M作为输入,输出一个比特值b。b=1意味着验证通过。b=0意味着验证不通过。在RSA签名中,验证算法首先计算M'=sigma^e mod N,随后对比M'与M,如果相等,则输出b=1,否则输出b=0。注意:验证算法和RSA加密体制中的加密算法非常像

    所以,在签名算法中,私钥用于对数据进行签名,公钥用于对签名进行验证。这也可以直观地进行理解:对一个文件签名,当然要用私钥,因为我们希望只有自己才能完成签字。验证过程当然希望所有人都能够执行,大家看到签名都能通过验证证明确实是我自己签的。

    =================分割线=================

    那么,为什么题主问这么一个问题呢?我们可以看到,RSA的加密/验证,解密/签字过程太像了。同时,RSA体制本身就是对称的:如果我们反过来把e看成私钥,d看成公钥,这个体制也能很好的执行。我想正是由于这个原因,题主在学习RSA体制的时候才会出现这种混乱。

    那么建议题主可以学习一下其他的公钥加密体制以及签名体制。其他的体制是没有这种对称性质的。举例来说,公钥加密体制的话可以看一看ElGamal加密,以及更安全的Cramer-Shoup加密。签名体制的话可以进一步看看ElGamal签名,甚至是BLS签名,这些体制可能能够帮助题主更好的弄清加密和签名之间的区别和潜在的联系。

    至于题主问的加密和签名是怎么结合的。这种体制叫做签密方案(SignCrypt),RSA中,这种签密方案看起来特别特别像,很容易引起混乱。在此我不太想详细介绍RSA中的加密与签字结合的方案。我想提醒题主的是,加密与签字结合时,两套公私钥是不同的


     

    这篇文章可以补充:http://blog.csdn.net/21aspnet/article/details/7249401

    这篇文章里:

    RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。 

    总结:公钥和私钥是成对的,它们互相解密。公钥不能用公钥解密。

    公钥加密,私钥解密。

    私钥数字签名,公钥验证。

    以下内容来自 http://blog.csdn.net/fivedoumi/article/details/31410181 讲的不细,权当了解。

    非对称加密经常用在基于证书的认证

    近年来相当流行的认证技术应该是基于证书的认证。其实证书就是一个数据块,主要包括公开密钥、主体相关的信息、证书有效的日期、证书发行者的信息和证书发行者生成的签名。
    
    已经谈过将公钥技术反过来可以应用于数字签名。但这种前面谁都可以签的,数字签名仅仅能解决消息来源真是你拥有公钥的主人,但并不能说明该主人就是合法的。但我们可去找一个特别了解此人的人(当然要权威了),问问看此人是否信得过。我们经常说的CA机构就是干这事情的。
    
    其实整个过程很简单,基本是二次数字签名。第一次首先需要证书的实体将自己的信息和公钥提交给CA,CA确认该组织的可信赖之后,就用自己的密钥对该实体的信息和公钥进行签名。最后被签名的信息会就叫证书。站在用户的角度,用户首先接到一个证书,当然会根据CA(可信)提供的公钥进行解密,如果能解密,当然就可以获得可信赖的信息和实体公钥。然后由实体公钥再进行前面我们介绍的数字签名解密步骤。

    安全套接字层

    安全套接字层(SSL)和取代它的传输层安全性(TLS)是用于在客户机和服务器之间构建安全的通信通道的协议。它也用来为客户机认证服务器,以及(不太常用的)为服务器认证客户机。该协议在浏览器应用程序中比较常见,浏览器窗口底部的锁表明 SSL/TLS 有效。
    
    SSL/TLS 使用本教程中已经讨论过的三种密码术构件的混合体,但这一切都是对用户透明的。以下是该协议的简化版本:
    ·    当使用 SSL/TLS(通常使用 https:// URL)向站点进行请求时,从服务器向客户机发送一个证书。客户机使用已安装的公共 CA 证书通过这个证书验证服务器的身份,然后检查 IP 名称(机器名)与客户机连接的机器是否匹配。
    ·    客户机生成一些可以用来生成对话的私钥(称为会话密钥)的随机信息,然后用服务器的公钥对它加密并将它发送到服务器。服务器用自己的私钥解密消息,然后用该随机信息派生出和客户机一样的私有会话密钥。通常在这个阶段使用 RSA 公钥算法。
    ·    然后,客户机和服务器使用私有会话密钥和私钥算法(通常是 RC4)进行通信。使用另一个密钥的消息认证码来确保消息的完整性。      

      

  • 相关阅读:
    【C语言篇】☞ 2. 常量、变量、scanf函数和printf 函数
    【C语言篇】☞ 1. 前言、基础
    React快速入门教程
    数论-欧拉函数
    数论-约数
    数论-质数专题
    匈牙利算法求二分图的最大匹配数
    染色法判断二分图
    Kruskal算法
    Prim算法
  • 原文地址:https://www.cnblogs.com/charlesblc/p/6130433.html
Copyright © 2011-2022 走看看