07 - RSA算法

2021-04-21  本文已影响0人  卡布奇诺_95d2

RSA算法的简介

在1976年以前,所有的加密方法都是同一种模式:加密、解密使用同一种算法。在交互数据的时候,彼此通信的双方就必须将规则告诉对方,否则没法解密。那么加密和解密的规则(简称密钥),它保护就显得尤其重要。传递密钥就成为了最大的隐患。这种加密方式被成为对称加密算法(symmetric encryption algorithm)。

1976年,两位美国计算机学家迪菲(W.Diffie)、赫尔曼(M.Hellman) 提出了一种崭新构思,可以在不直接传递密钥的情况下,完成密钥交换。这被称为“迪菲赫尔曼密钥交换”算法。开创了密码学研究的新方向.

1977年,三位麻省理工学院的数学家罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起设计了一种算法,可以实现非对称加密。这个算法用他们三个人的名字命名,叫做RSA算法。

RSA算法的运算特点

  1. 由于RSA都是大数运算,因此,RSA最快的情况下也要比DES慢上好几倍。
  2. RSA的速度比对应同样安全级别的对称加密算法要慢1000倍左右。
  3. 速度一直是RSA的缺陷,所以大量的数据并不适合RSA,一般来说,RSA只适用于少量数据的加密。
  4. 日常开发中,大数据采用对称加密,如DES。而对称加密使用的密钥则通过RSA加密。

通过终端命令进行RSA运算

Mac终端内置了开源密码库OpenSSL,所以在终端上可以直接使用命令运行RSA。

常用的指令有三个:

  1. genrsa:生成并输入一个RSA私钥。
  2. rsautl:使用RSA密钥进行加密、解密、签名和验证运算。
  3. rsa:处理RSA密钥的格式转换。

openssl genrsa指令

openssl genrsa [-out filename] [-passout arg] [-des] [-des3] [-idea] [numbits]

openssl rsautl指令

openssl rsautl [-in file] [-out file] [-inkey file] [-passin arg] [-keyform PEM|DER|NET] [-pubin] [-certin] [-asn1parse] [-hexdump] [-raw] [-oaep] [-ssl] [-pkcs] [-x931] [-sign] [-verify][-encrypt] [-decrypt] [-rev] [-engine e]

openssl rsa指令

openssl rsa [-inform PEM|NET|DER] [-outform PEM|NET|DER] [-in filename] [-passin arg] [-out filename] [-passout arg] [-sgckey] [-text] [-noout] [-modulus] [-check] [-pubin] [-pubout] [-engine id] [-des] [-des3] [-idea]

生成公私钥对

~/rsaTest: openssl genrsa -out private.pem 1024
Generating RSA private key, 1024 bit long modulus (2 primes)
....................+++++
.....................+++++
e is 65537 (0x010001)

此时已经生成了一个 private.pem 的私钥

~/rsaTest:ls
private.pem
~/rsaTest:cat private.pem
-----BEGIN RSA PRIVATE KEY-----
MIICXQIBAAKBgQDl9avuiPkGLCov7+Mu0n+p7+2e8uguByR1gL2ftq4G/yBC6p7+
i85Ftu3Lj9aYAEnI/jUKC/lM791RzltAVFeJj9JhG3OlD+k+omygbCe3NFqLjFs7
nIYnaHhHPWVBQcypyI5pQ+bvNwvCsVMpRAOmodIQyJiRmuKkNsSmpPsOWwIDAQAB
AoGBALcpftB3+SGZe+DCyck5kMXifPnlsFk5BykwadkUwHiCLUgfaJSG9r1Afxds
chiP4jVdhRGDiAZn53iJTNVoWG+OPuM8vf00tvr1u8igtMsYTxTZhLUaCkigi+a0
ga9d6m737CfzS1XfoizDknkNPQmCSVvIs29Vi1tOUfc1JrABAkEA/3wpxcy6YT7M
txlzd658TgZjdM2c0yohc/DlD71+U93pTGY+7RqBxQXvkQF6UoKq6lbafB+UlRaM
CEgQkvfNWwJBAOZsVjGXGJKNzlSscLqTxc0hSM9bA/n5GhuBREe+a2alXGNilcN/
wlUlgQVokrxZ/biQ1t9J/Hf0Q/9XU4jIkwECQQD/Yza+q3CEVSp+vcpXEOzhcjFp
SUBDNhJKu7u+iEYHwAS+glbU3XJraQuZgEiuwj/oEPpGqar1fZxtitxGjb+RAkAH
V1xHqDC4OpxgRj4xM5QRvQW81YGC7VTPm4a5Ym+5jXssD3AGEoP2goNh0LscFSHo
R3URGCJbEAU6lWWr7fgBAkBJU5xa0538yhZshCmRlKagOmKItQ97U7IvvO65/by3
BTiWyB88h1eLe6go4zzkuvWzcKl8kBIVg5LJL7+nfzKJ
-----END RSA PRIVATE KEY-----
~/rsaTest:openssl rsa -in private.pem -pubout -out public.pem
writing RSA key

此时在目录下有一个公钥文件 public.pem

~/rsaTest: ls
private.pem public.pem
~/rsaTest: cat public.pem
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDl9avuiPkGLCov7+Mu0n+p7+2e
8uguByR1gL2ftq4G/yBC6p7+i85Ftu3Lj9aYAEnI/jUKC/lM791RzltAVFeJj9Jh
G3OlD+k+omygbCe3NFqLjFs7nIYnaHhHPWVBQcypyI5pQ+bvNwvCsVMpRAOmodIQ
yJiRmuKkNsSmpPsOWwIDAQAB
-----END PUBLIC KEY-----

使用公钥加密文件、私钥解密文件

openssl rsault -encrypt -in message.txt -inkey public.pem -pubin -out enc.txt

//加密后查看加密文件
~/saTest: ls
enc.txt     message.txt private.pem public.pem

//注意加密后的数据为二进制数据,因此结果在终端显示为乱码,可通过base64将其转换成可读的字符串。
cat enc.txt | base64
3NauYaD6z+LBxCMuSv6MpJuoJ8KLp3cvAVOdX1JlZyPYdEvGLGLXawiUPIKmpwWl+fAmkqQhl86nCMIPod5MXw9IO8qqsBYZdm+UU/EyimxAKVzpefjdyBp9k68CHoEbWEGod1wcvPz843xYkGGk3Pgze2AqjfvJQEDgIwVFUVs=
openssl rsautl -decrypt -in enc.txt -inkey private.pem -out dec.txt

//解密后的结果
~/rsaTest:ls
dec.txt enc.txt message.txt private.pem public.pem

~/rsaTest:cat dec.txt
hello RSA!

注意:在终端中,-encrypt-decrypt参数是公钥加密,私钥解密。其实RSA还可以使用私钥加密、公钥解密,但指令需要变成-sign-verify,后续在代码中会体现。

使用公钥对文件签名、私钥验证文件签名

~/rsaTest:openssl rsautl -sign -in message.txt -inkey private.pem -out enc.txt

~/rsaTest:cat enc.txt | base64
z1WQA9ki5HvZh8bF2HbNxCLG63i3geVWgCzorBsWm6KqXZNGdfTY/KYR28il0ou9R5xKjfKUzzLGuoGjKHco2HBASA2tPfIj6Vz7Ze5ARAEjR8Z/R+uvKXx9T5xNrazVLne4oDS8XTgW3aW4Da728pzCPegNlwtRczlinSdHP64=

~/rsaTest:openssl rsautl -verify -in enc.txt -inkey public.pem -pubin -out dec.txt

~/rsaTest:cat dec.txt
hello RSA!

代码实现RSA算法

在iOS中无法直接使用扩展名为PEM的文件。在代码中,需要将PEM编码的文件转换成DER证书文件和P12证书文件。

【步骤1】根据RSA私钥生成一个证书请求文件CSR
CSR:Certificate Signing Request,即证书签名请求,这个并不是证书,而是向权威证书颁发机构获得签名证书的申请,其核心内容是一个公钥(当然还附带了一些别的信息),在生成这个申请的时候,同时也会生成一个私钥,私钥要自己保管好.

openssl req -new -key private.pem -out rsacert.csr

You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) []:CN
State or Province Name (full name) []:SZ
Locality Name (eg, city) []:SZ
Organization Name (eg, company) []:HQ
Organizational Unit Name (eg, section) []:HQ
Common Name (eg, fully qualified host name) []:HQ
Email Address []:tiramisu131@sina.com

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:123456

此时通过私钥生成了一个.csr证书请求文件,将其发给颁发证书的机构进行签名,或者进行自签名。

【步骤2】对.csr文件自签名,生成.crt证书
CRT:是certificate的三个字母,是证书的意思,常见于*NIX系统,有可能是PEM编码,也有可能是DER编码,大多数应该是PEM编码。

openssl x509 -req -days 3650 -in rsacert.csr -signkey private.pem -out rsacert.crt
Signature ok
subject=C = CN, ST = SZ, L = SZ, O = HQ, OU = HQ, CN = HQ, emailAddress = tiramisu131@sina.com
Getting Private key

//此时已经生成CRT证书,可通过cat命令查看该证书
cat rsacert.crt

-----BEGIN CERTIFICATE-----
MIICaDCCAdECFFbUaWYruhP+p4y3ZaRl/e6epK7lMA0GCSqGSIb3DQEBCwUAMHMx
CzAJBgNVBAYTAkNOMQswCQYDVQQIDAJTWjELMAkGA1UEBwwCU1oxCzAJBgNVBAoM
AkhRMQswCQYDVQQLDAJIUTELMAkGA1UEAwwCSFExIzAhBgkqhkiG9w0BCQEWFHRp
cmFtaXN1MTMxQHNpbmEuY29tMB4XDTIxMDQyMTA3MDYzMFoXDTMxMDQxOTA3MDYz
MFowczELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNaMQswCQYDVQQHDAJTWjELMAkG
A1UECgwCSFExCzAJBgNVBAsMAkhRMQswCQYDVQQDDAJIUTEjMCEGCSqGSIb3DQEJ
ARYUdGlyYW1pc3UxMzFAc2luYS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBAOX1q+6I+QYsKi/v4y7Sf6nv7Z7y6C4HJHWAvZ+2rgb/IELqnv6LzkW27cuP
1pgAScj+NQoL+Uzv3VHOW0BUV4mP0mEbc6UP6T6ibKBsJ7c0WouMWzuchidoeEc9
ZUFBzKnIjmlD5u83C8KxUylEA6ah0hDImJGa4qQ2xKak+w5bAgMBAAEwDQYJKoZI
hvcNAQELBQADgYEAlQZfGvYl2EbsuuNrcMwu5v6oGu+HgkvAOhRyR6+/NSooqj1o
uInm1lmDcPGamABWX6gt1quHTSqDXoAYGVKXgM+u1h4iKM0oGcR5uoIyVgooEWHl
RnAGyZTAd20VlDyGJM9zmff9CDE4WfUCHo0WdJIBBpRgxa3YZ9nEPCuenTE=
-----END CERTIFICATE-----

注意:自签名证书仅是用来演示的,不受各类浏览器等信任。

【步骤3】将CRT证书转换成DER证书,DER证书中包含公钥。

openssl x509 -outform der -in rsacert.crt -out rsacert.der

//查看DER证书信息
openssl x509 -in rsacert.der -inform der -text -noout

Certificate:
    Data:
        Version: 1 (0x0)
        Serial Number:
56:d4:69:66:2b:ba:13:fe:a7:8c:b7:65:a4:65:fd:ee:9e:a4:ae:e5
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = CN, ST = SZ, L = SZ, O = HQ, OU = HQ, CN = HQ, emailAddress = tiramisu131@sina.com
        Validity
            Not Before: Apr 21 07:06:30 2021 GMT
            Not After : Apr 19 07:06:30 2031 GMT
        Subject: C = CN, ST = SZ, L = SZ, O = HQ, OU = HQ, CN = HQ, emailAddress = tiramisu131@sina.com
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (1024 bit)
                Modulus:
00:e5:f5:ab:ee:88:f9:06:2c:2a:2f:ef:e3:2e:d2:
7f:a9:ef:ed:9e:f2:e8:2e:07:24:75:80:bd:9f:b6:
ae:06:ff:20:42:ea:9e:fe:8b:ce:45:b6:ed:cb:8f:
d6:98:00:49:c8:fe:35:0a:0b:f9:4c:ef:dd:51:ce:
5b:40:54:57:89:8f:d2:61:1b:73:a5:0f:e9:3e:a2:
6c:a0:6c:27:b7:34:5a:8b:8c:5b:3b:9c:86:27:68:
78:47:3d:65:41:41:cc:a9:c8:8e:69:43:e6:ef:37:
0b:c2:b1:53:29:44:03:a6:a1:d2:10:c8:98:91:9a:
e2:a4:36:c4:a6:a4:fb:0e:5b
                Exponent: 65537 (0x10001)
    Signature Algorithm: sha256WithRSAEncryption
95:06:5f:1a:f6:25:d8:46:ec:ba:e3:6b:70:cc:2e:e6:fe:a8:
1a:ef:87:82:4b:c0:3a:14:72:47:af:bf:35:2a:28:aa:3d:68:
b8:89:e6:d6:59:83:70:f1:9a:98:00:56:5f:a8:2d:d6:ab:87:
4d:2a:83:5e:80:18:19:52:97:80:cf:ae:d6:1e:22:28:cd:28:
19:c4:79:ba:82:32:56:0a:28:11:61:e5:46:70:06:c9:94:c0:
77:6d:15:94:3c:86:24:cf:73:99:f7:fd:08:31:38:59:f5:02:
1e:8d:16:74:92:01:06:94:60:c5:ad:d8:67:d9:c4:3c:2b:9e:
9d:31

注意:此时DER证书是二进制格式的,无法直接通过cat命令查看,若需要查看,可通过openssl x509 -in rsacert.der -inform der -text -noout查看证书信息。

【步骤4】通过私钥和.crt证书,导出.p12证书,(.p12证书包含私钥)

openssl pkcs12 -export -out p.p12 -inkey private.pem -in rsacert.crt
Enter Export Password:(输入时密码隐藏不显示)
Verifying - Enter Export Password:(输入时密码隐藏不显示)

【步骤5】新建RSADemo项目,并将.der和.p12文件增加到工程中。并增加加载公钥和私钥的代码,以及增加加密、解密的测试代码。具体代码请查看文末Demo。

总结:

  1. RSA加密有三种填充方式:
    1. kSecPaddingNone:不填充,即:如果明文不够128字节,加密时会在明文前面,前向填充零。因此每次生成的加密结果一样
    2. kSecPaddingPKCS1:最常用的填充方式,默认为该方式。如果明文不够128字节,会在明文中随机填充一些数据,所以会导致对同样的明文每次加密后的结果都不一样
    3. kSecPaddingOAEP:PKCS#1推出的新的填充方式,安全性是最高。和kSecPaddingPKCS1的区别就是加密前的编码方式不一样
  2. RSA特点:
    1. 加密安全系数高
    2. 加密效率低
    3. 不适用于加密大数据,适用于加密关键数据,常配合对称密钥使用
  3. RSA算法中常用指令
    1. genrsa:生成一个RSA私钥
    2. rsault:使用RSA密钥进行加密、解密、签名、验证等运算
    3. rsa:处理RSA密钥的格式转换等问题

演示案例请前往Demo

上一篇 下一篇

猜你喜欢

热点阅读