加密算法_非对称加密RSA与DSA

RSA

原理:安全性来源于两个大质数P和Q相乘容易,分解难.加密的最底层是基于大质数难分解的性质.

算法的处理细节:详细如下

加密处理

加密是求“明文的E次方的 mod N”,

解密则是求“密文的D次方的 mod N”。

密钥的产生

公钥:E和N

私钥:D和N

由于E和N是公钥,D和N是私钥,因此求E、D和N这三个数就是生成密钥对。RSA密钥对的生成步骤如下:

  1. 求N
  2. 求L( L是仅在生成密钥对的过程中使用的数)
  3. 求E
  4. 求D

求N

首先准备两个很大的质数。这两个很大的质数为p和q。p和q太小的话,密码会变得容易破译,但太大的话计算时间又会变得很长。

判断一个数是不是质数并不是看它能不能分解质因数,而是通过数学上的判断方法来完成。

准备好两个很大的质数之后,我们将这两个数相乘,其结果就是数N。也就是说,数 N 可以用下列公式来表达:

1
N = p x q (p、q为质数)

求L

L 这个数在RSA的加密和解密过程中都不出现,它只出现在生成密钥对的过程中。

Lp-1q-1 的最小公倍数( least common multiple, lcm )。

如果用lcm(X, Y) 来表示 “X和Y的最小公倍数”,则L可以写成下列形式。

1
L= lcm(p-1,q-1) ( L是p-1和q-1的最小公倍数)

求E

E是一个比1大、比L小的数。此外,E和L的最大公约数( greatest common divisor, gcd)必须为1。

如果用gcd(X, Y)来表示X和Y的最大公约数,则E和L之间存在下列关系。

1
2
1 < E < L
gcd(E,L)= 1

求D

数D是由数E计算得到的。D、E和L之间必须具备下列关系。

1
2
1 < D < L
E x D mod L = 1

###

##

功能场景的应用:

数据加密:

签名验证:

所谓验证:用公钥成功解开信息,我们有理由相信,收到的信息就是私钥持有人所发送.

实现方法:

私钥持有人 发送一则信息A私钥处理过的的信息A+

公钥持有人 验证信息A用公钥处理过的A+是否一致

我们常说的网站数字签名证书是怎么完成的?

生活中经常遇到假冒银行,交易所的网站,为了辨识不法网络攻击者,假冒克隆官方网站;

国际上成立了证书机构CA,嵌入在浏览器中,正规公司自己生成一对密钥,将公钥交给CA保管;

栗子:每当我们打开币网交易平台,我们的电脑会收到币网的数字证书,此时电脑嵌入的证书插件,会自动在网上下载对应'币网'的公钥,进行验证,验证通过,说明核实了当前登陆的网站身份.

附上在go中,调用RSA加密的代码demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main

import (
"crypto/rsa"
"crypto/rand"
"fmt"
"crypto/md5"
"encoding/base64"
)

//
//利用RSA的方法生成密钥对


func main(){
//首先生成私钥,根据私钥产生公钥

pri,_:=rsa.GenerateKey(rand.Reader,1024)


//根据私钥产生公钥
pub:=&pri.PublicKey

//fmt.Println("私钥地址:",pri)
//fmt.Println("公钥地址:",pub)

//定义明文
oriMess:=[]byte("hello china")
//加密成密文
cipherMess,_:=rsa.EncryptOAEP(md5.New(),rand.Reader,pub,oriMess,nil)

fmt.Println("加密:",base64.StdEncoding.EncodeToString(cipherMess))

////解密
oriMess,_=rsa.DecryptOAEP(md5.New(),rand.Reader,pri,cipherMess,nil)
fmt.Println("解密:",string(oriMess))

}

输出结果

加密: pdsBqvpQ6PB2l/5chgKT9NiCycdz4lE2SdzuSrFPT+XNJ5SnksShaaB+NymNxDRHA+MLv+76xZeBbYLzj8mUklsBeMHx84rWaZHhqEroGEyLRVc9IId6Vg5982LaOZZUJRs2kO3uH4Bc4+oTkBfDpspzq9ejiL+ym+BLv+b/gM0=
解密: hello china