美文网首页
07 - RSA算法

07 - RSA算法

作者: 卡布奇诺_95d2 | 来源:发表于2021-04-21 16:01 被阅读0次

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指令

  • 功能
    用于生成RSA私钥,不会生成公钥,因为公钥提取自私钥
  • 用法
openssl genrsa [-out filename] [-passout arg] [-des] [-des3] [-idea] [numbits]
  • 选项说明
    1. -out filename:将生成的私钥保存至filename文件,若未指定输出文件,则为标准输出
    2. -passout arg:加密私钥文件时,传递密码的格式,如果要加密私钥文件时但未指定该项,则提示输入密码,传递密码的args的格式如下:
      1. pass:password:password表示传递的明文密码
      2. env:var:从环境变量var获取密码值
      3. file:filename:filename文件中的第一行为要传递的密码。若filename同时传递给"-passin"和"-passout"选项,则filename的第一行为"-passin"的值,第二行为"-passout"的值
      4. stdin:从标准输入中获取要传递的密码
    3. -des | -des3 | -idea:指定加密私钥文件用的算法,这样每次使用私钥文件都将输入密码,太麻烦所以很少使用
    4. numbits:指定要生成的私钥的长度,默认为1024。该项必须为命令行的最后一项参数

openssl rsautl指令

  • 功能
    使用RSA算法签名,验证身份,加密/解密数据

  • 用法

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]
  • 选项说明
    1. -in file:需要处理的文件,默认为标准输入
    2. -out file:指定输出文件名,默认为标准输出
    3. -inkey file:指定我们的密钥文件
    4. -passin arg:指定密钥包含口令存放方式
    5. -keyform PEM|DER|NET:私钥格式,默认是PEM
    6. -pubin:表明当前输入的是公钥文件,默认是私钥文件
    7. -certin:表明输入是一个承载RSA公钥的证书文件
    8. -asn1parse:对输出的数据进行ASN1分析
    9. -hexdump:用十六进制输出数据
    10. -raw、-oaep、-ssl、-pkcs、-x931:采用的填充模式
    11. -sign:给输入的数据签名。需要我们的私有密钥文件
    12. -verify:对输入的数据进行验证
    13. -encrypt:用我们的公共密钥对输入的数据进行加密
    14. -decrypt:用RSA的私有密钥对输入的数据进行解密
    15. -rev:数据是否倒序
    16. -engine e:硬件引擎

openssl rsa指令

  • 功能
    用于处理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]
  • 选项说明
    1. -inform PEM|NET|DER:输入文件格式,默认为PEM格式
    2. -outform PEM|NET|DER:输出文件格式,默认为PEM格式
    3. -in filename:输入文件
    4. -passin arg:指定输入文件的加密口令,同openssl genrsa一样,可来自文件、终端、环境变量等
    5. -out filename:输出文件
    6. -passout arg:指定输出文件的加密口令,可来自文件、终端、环境变量等
    7. -sgckey:指定SGC编码格式,兼容旧版本,不应再使用
    8. -text:以明文形式输出各个参数值
    9. -noout:不输出密钥到任何文件
    10. -modulus:输出模数指
    11. -check:检查输入密钥的正确性和一致性
    12. -pubin:指定输入文件是公钥
    13. -pubout:指定输出文件是私钥
    14. -engine id:指定三方加密库或硬件
    15. -des:使用CBC DES加密输出的文件
    16. -des3:使用3DES加密输出的文件
    17. -seed:使用CBC seed加密输出的文件
    18. -aes128, -aes192, -aes256:使用AES加密输出的文件
    19. -camellia128, -camellia192, -camellia256:使用camellia加密输出的文件
    20. -idea:使用CBC idea加密输出的文件

生成公私钥对

  • 【步骤1】生成RSA私钥
~/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-----
  • 【步骤2】从私钥文件中提取公钥
~/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-----

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

  • 【步骤1】创建一个待加密的文件(message.txt),文件中内容为”hello RSA!“。

  • 【步骤2】使用公钥对文件(message.txt)进行加密,并将加密结果存入文件(enc.txt)

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=
  • 【步骤3】使用私钥对文件(enc.txt)进行解密,并将解密后的结果存入文件(dec.txt)
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

相关文章

  • 07 - RSA算法

    RSA算法的简介 在1976年以前,所有的加密方法都是同一种模式:加密、解密使用同一种算法。在交互数据的时候,彼此...

  • RSA算法原理(作者: 阮一峰)

    RSA算法原理(一) RSA算法原理(二) RSA C算法实现【 看雪安全论坛】

  • # RSA 公钥加密算法

    # RSA 公钥加密算法 # RSA 公钥加密算法

  • 6.1 密码学专题 - 非对称加密算法 - RSA 算法

    密码学专题 - 非对称加密算法 - RSA 算法 6.1 RSA 算法 第一个较完善的非对称加密算法 RSA,它既...

  • angularjs和vue实现RAS加密

    一. 什么是RSA?RSA算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法。在了解RSA算法之前...

  • RSA加密算法详解

    什么是RSA算法? RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是197...

  • RSA加密原理解析

    1. 什么是RSA RSA算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法。在了解RSA算法之前...

  • RAS加解密详解

    1. 什么是RSA RSA算法是现今使用最广泛的公钥密码算法,也是号称地球上最安全的加密算法。在了解RSA算法之前...

  • 密码学第二次实验报告:RSA算法

    实验题目 RSA算法 实验目的 了解公钥算法基本原理和RSA算法的原理。了解RSA算法在数据加密和数字签名中的应用...

  • rsa算法

    rsa算法

网友评论

      本文标题:07 - RSA算法

      本文链接:https://www.haomeiwen.com/subject/gqdzlltx.html