美文网首页TPM 2.0及密码学入门
基础练习: 使用openssl命令创建RSA密钥

基础练习: 使用openssl命令创建RSA密钥

作者: 阿群1986 | 来源:发表于2017-07-19 11:05 被阅读78次

    本文大部分内容参考自:
    http://blog.csdn.net/zhymax/article/details/7683925 《使用openssl命令剖析RSA私钥文件格式》
    原作者博客: http://blog.csdn.net/zhymax
    阿群做了整理

    预备知识1:输出文件的编码格式

    PEM编码(Privacy Enhanced Mail)
    特点:纯文本文件, 以-----BEGIN 某某某-----开头, 以-----END 某某某-----结尾, 内容是 base64 编码.
    备注:使用文本编辑器只能查看或复制文本而不能修改, 解码后底层的二进制数据结构仍需要借助openssl命令行工具才能解读.

    PKCS#8格式是一种主流的密钥存储格式, 采用PEM编码方式来存储底层的ASN.1结构体二进制数据.
    OpenSSL从1.0.0版本开始把PKCS#8格式作为默认的密钥文件存储格式.
    存储密钥时可选加密口令格式或直接存储明文格式两种.

    • PKCS#8 私钥加密格式, 以-----BEGIN ENCRYPTED PRIVATE KEY-----开头. 参见【练习1】
    • PKCS#8 私钥非加密格式, 以-----BEGIN PRIVATE KEY-----开头. 参见【练习2】

    打开此类纯文本格式的密钥文件, 通过标题行可以判断上述两种密钥文件是否需要输入解锁口令.
    PEM编码虽然是纯文本, 但仍然要先还原回二进制数据之后才能取出 RSA 密钥的详细信息.
    我们借助openssl命令行工具来查看一个RSA密钥包括的各个字段.

    openssl命令入门

    openssl命令由多个自命令组成, 需要掌握下列命令的调用参数

    1. 密钥的创建命令openssl genpkey
    2. 单独提取公钥部分, 通过openssl pkey命令完成
    3. 输出密钥详细信息, 分别通过openssl rsa命令和openssl as1nparse命令
      前者只输出RSA密钥的数字, 后者逐层解析ASN.1二进制数据结构体格式(一般不常用)
    4. 常用的签名/校验签名/RSA加密/RSA解密: 分别使用openssl rsautl命令的-sign、-verify、-encrypt、-decrypt选项

    【练习1】:
    第一步、从命令行创建一个受口令保护的RSA密钥文件key1.pem,
    选项-pass指定解锁口令为1234, 选项-aes128指定解锁过程采用的是128位AES对称加密

    openssl genpkey -algorithm RSA -out key1.pem -pass pass:1234 -aes128
    

    第二步、从key1.pem中取出这个密钥的公钥部分, 另存为pub1.pem:

    openssl pkey -in key1.pem -out pub1.pem -pubout
    

    最后依次查看密钥的公钥信息和私钥信息
    只查看公钥信息时不需要口令

    openssl rsa -pubin -in pub1.pem -text -noout
    openssl rsa -in key1.pem -text -noout
    

    上述四个命令在阿群的Linux终端中执行时, 屏幕输出的结果依次如下:

    <pre>$ openssl genpkey -algorithm RSA -out key1.pem -pass pass:1234 -aes-128-cbc
    ...........++++++
    ...................++++++
    $ openssl pkey -in key1.pem -out pub1.pem -pubout
    Enter pass phrase for key1.pem: (注: 此处提示我们输入解锁口令,即1234)
    </pre>
    打开两个输出文件key1.pem和pub1.pem(或从终端输入命令cat key1.pemcat pub1.pem
    <pre>-----BEGIN ENCRYPTED PRIVATE KEY-----
    MIICzzBJBgkqhkiG9w0BBQ0wPDAbBgkqhkiG9w0BBQwwDgQIGx4mWhx1mEcCAggA
    MB0GCWCGSAFlAwQBAgQQfOdchM4ftSARZ9jZdS7F0wSCAoBb0aUTyrKlX5XULHhV
    MXvAmP1AQNqj1Dos5So6UGHYi3y0/gbK6TsirJOquQ/MCEKD8F/4yqdWg8FgN/J5
    epa3afmbRivkOwmthK/pl0vffoOGDqPndo/weTwpzBHAGRM7KmM2iURmU7wublQL
    H9oec//jfVtjGVBshqpzf2Wkmt8svp+30itftKn5cUrHFwDQBhDqUO9OnxSg+DNt
    Yyo2a4nxo6XncydEb+QoYQIM8jisGzcdkkw5rquLJlUQTDHTM8urIwwlqrwWp0iN
    2P+F4AWfAKK+/lZRpLxdTCNa5wvgwwxh1TizKDnqcOO2jlVXxYyZycCabcnQUKFa
    oMOjuOiiLGHi/1fDQYn2bLCtXg2DZQ6pvEOdqAsPgZFzKZv2VMUZ/knMG3zcC2pG
    3ff7Tf6E3drLQTxR7MjyUKlDL3HM/NifQubwAbG2l/4xVrRHK13nMymtHC42eyuJ
    Qi6EHUHAxnoHv+KgA4IKK7b3UwPFQqsgokLOLcslRZnsZtHrMsa+7qBUrJL9bvYB
    54lC7VUXAB5OJv8kjHr9eRPY9TdP9vP9YsYh8nH7t2CdUH9r8iUyukhBmylhmjy6
    JvMpfkjIHvHn3lHuxdt5s3hPLVh+bcaYHUClcHJPk8BbUZpeuFQT4UpBpauxLcHm
    G96ElmLMAHRAVfGIuXUvusdJZNb3IMgpk6A7mXwVHvc9Mk3RO96bfKURGVIbyg9U
    BT+bfGJ+rnJyWvc+yiG37KfYDVuBWw9tRhgbQ52CHHxxJgaHb3NQo9je3SMyvHs+
    xieDQ7Vgk6QNd1e7Jckz2NuHEMhvxRDjR3smG0t5ExWyUXQL8hNWuRfRKzjc3FBR
    GrUu
    -----END ENCRYPTED PRIVATE KEY-----
    </pre>

    <pre>-----BEGIN PUBLIC KEY-----
    MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtBrMwAiE0yFYNm0MAIWtKf9Yj
    h1LYZVniVsAaujzq77E5R8Wc04kOFT6mn/la4xn10fIw8tjkMT12MqWf/i9ShWjm
    fFYGCQP0YUx/2F7ngt5gTvkCgCMT8l6UfXejnOsPNojmOh5FkDpqwqewZCRc87+1
    kWvqeqRNGHuh98xeMwIDAQAB
    -----END PUBLIC KEY-----
    </pre>

    <pre>$ openssl rsa -pubin -in pub1.pem -text -noout
    Public-Key: (1024 bit)
    Modulus:
    00:ad:06:b3:30:02:21:34:c8:56:0d:9b:43:00:21:
    6b:4a:7f:d6:23:87:52:d8:65:59:e2:56:c0:1a:ba:
    3c:ea:ef:b1:39:47:c5:9c:d3:89:0e:15:3e:a6:9f:
    f9:5a:e3:19:f5:d1:f2:30:f2:d8:e4:31:3d:76:32:
    a5:9f:fe:2f:52:85:68:e6:7c:56:06:09:03:f4:61:
    4c:7f:d8:5e:e7:82:de:60:4e:f9:02:80:23:13:f2:
    5e:94:7d:77:a3:9c:eb:0f:36:88:e6:3a:1e:45:90:
    3a:6a:c2:a7:b0:64:24:5c:f3:bf:b5:91:6b:ea:7a:
    a4:4d:18:7b:a1:f7:cc:5e:33
    Exponent: 65537 (0x10001)
    </pre>

    <pre>$ openssl rsa -in key1.pem -text -noout
    Enter pass phrase for key1.pem: (注: 此处提示我们输入解锁口令,即1234)
    Private-Key: (1024 bit)
    modulus: --【模数n】
    00:ad:06:b3:30:02:21:34:c8:56:0d:9b:43:00:21:
    6b:4a:7f:d6:23:87:52:d8:65:59:e2:56:c0:1a:ba:
    3c:ea:ef:b1:39:47:c5:9c:d3:89:0e:15:3e:a6:9f:
    f9:5a:e3:19:f5:d1:f2:30:f2:d8:e4:31:3d:76:32:
    a5:9f:fe:2f:52:85:68:e6:7c:56:06:09:03:f4:61:
    4c:7f:d8:5e:e7:82:de:60:4e:f9:02:80:23:13:f2:
    5e:94:7d:77:a3:9c:eb:0f:36:88:e6:3a:1e:45:90:
    3a:6a:c2:a7:b0:64:24:5c:f3:bf:b5:91:6b:ea:7a:
    a4:4d:18:7b:a1:f7:cc:5e:33
    publicExponent: 65537 (0x10001) --【公钥指数e】
    privateExponent: --【私钥指数d】
    65:6c:57:fc:fc:42:9a:be:14:33:45:9f:b0:a3:e6:
    50:75:3f:00:f4:82:0b:76:dd:89:5f:70:9c:3a:2f:
    1b:48:05:8a:9e:17:a8:26:17:60:b9:f3:4f:98:d6:
    82:00:3d:67:6a:f9:9c:d7:bd:6b:85:b1:91:67:7e:
    ce:9a:21:02:36:95:45:51:47:8d:33:e0:1b:c2:eb:
    f6:cc:4f:a8:3a:c3:8a:ff:13:79:a3:78:5f:26:24:
    6d:76:d2:92:c7:88:27:2b:87:96:3a:0b:1e:fa:42:
    2a:28:13:39:dd:29:d8:b3:eb:9d:8f:69:24:0d:1d:
    f8:69:11:9c:25:a6:92:81
    prime1: --【质数p】
    00:e6:3f:33:6b:19:69:e8:4f:39:e6:b4:ac:90:83:
    d4:49:b6:34:b6:08:7a:3f:f4:08:3b:f6:78:70:6d:
    e8:44:00:62:59:a7:2b:0d:75:8b:94:4a:5a:b7:e4:
    7e:c6:a4:1c:42:8b:9b:09:75:81:90:b5:34:0d:4f:
    f6:73:f1:1c:2d
    prime2: --【质数q】
    00:c0:61:10:51:71:b7:c5:fd:05:4e:b8:47:c3:7e:
    9a:75:1b:56:55:e2:66:67:ba:2b:9a:3c:0c:f1:35:
    98:a0:b5:0d:8b:6e:3f:60:0a:c2:43:cb:24:56:b1:
    e8:78:43:dd:8c:63:dc:4b:ff:05:ed:39:cd:9d:63:
    b7:f1:04:ff:df
    exponent1: --【d mod (p-1)】
    00:87:50:d5:73:37:f8:5a:23:55:b0:14:b6:e6:27:
    d3:f7:8e:31:e4:59:8f:1f:4e:d8:18:05:7e:3a:f5:
    1c:ef:fa:19:d2:fe:bf:fa:a4:fe:67:24:5b:b4:7f:
    81:52:54:d8:96:f3:5d:26:6d:fc:bb:83:03:18:5f:
    ca:43:d1:8b:f1
    exponent2: --【d mod (q-1)】
    63:12:d9:cb:87:cc:03:db:bd:5b:00:0e:7d:40:7b:
    1d:2a:39:f9:3b:02:50:13:11:97:79:ab:94:a1:6c:
    7b:ff:21:fd:97:86:6d:d8:bc:99:1b:4a:18:97:c0:
    c8:06:f3:56:f4:aa:a4:3c:ae:f9:af:d6:13:63:22:
    7c:ae:7d:73
    coefficient: --【(inverse of q) mod p 】
    00:9e:75:2a:b4:46:ef:3c:37:bd:c5:d4:7c:f9:60:
    89:af:05:55:3b:7c:47:a1:63:c0:cf:09:f9:47:7c:
    8e:6a:91:3f:7e:55:dc:5e:47:3e:37:a0:78:16:3c:
    de:17:9b:a3:67:a8:c8:a7:ee:d0:a0:99:b2:4a:d9:
    5e:60:5e:71:6f
    </pre>

    【练习2】:
    从命令行创建一个无口令保护的密钥key2.pem, 然后查看密钥信息.
    <pre>openssl genpkey -algorithm RSA -out key2.pem
    openssl rsa -in key2.pem -text -noout
    </pre>

    【练习3】: 使用前面自己创建的RSA密钥key1.pem对某个文件的哈希值进行数字签名
    openss rsautl -sign -in "输入任意长文件的SHA1哈希值20字节.hex" -inkey key1.pem -out "签名值.sig"
    (注: 计算长文件的SHA1哈希值可以使用命令sha1sum 某个长文件.txt, 但它输出的是一个纯文本字符串, 不是我们要的二进制数据. 可借助其他hex编辑器)

    【练习4】: 使用前面导出的公钥pub1.pem校验数字签名
    openss rsautl -verify -in "签名值.sig" -pubin -inkey pub1.pem -out "输出签名前原始的哈希值20字节.hex"


    下期预告

    关于 ssh-keygen 的一点疑问
    除了openssl之外, 还有好几种工具也可以生成RSA密钥文件, 包括OpenSSH的ssh-keygen,GnuPG的gpg等等.
    其中 ssh-keygen 输出的RSA密钥文件的版本较旧, 这种比较旧文件格式不同于PKCS#8标准. 但是openssl支持这种旧版密钥格式.

    相关文章

      网友评论

        本文标题:基础练习: 使用openssl命令创建RSA密钥

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