美文网首页JAVA进阶
Openssl库之RSA格式解析

Openssl库之RSA格式解析

作者: 猫咪不吃鱼 | 来源:发表于2021-10-09 16:01 被阅读0次

    ASN.1介绍

    Abstract Syntax Notation dot one,抽象语法标记,描述了一种对数据进行表示、传输和解码的数据格式。它提供了一整套正规的格式用于描述对象的结构。它包含两部分:一部分描述信息内数据,数据类型及序列格式;另一部分描述如何将各部分组成消息。而不管语言上如何执行及这些数据的具体指代,也不用去管到底是什么样的应用程序;

    结构定义

    ASN1有很多实现版本,Openssl主要采用DER格式,ASN1相关的头文件参见Openssl的源码 asn1.h、asn1t.h,如下所示:

    struct asn1_string_st {
        int length;
        int type;
        unsigned char *data;
        long flags;
    };
    

    ANS1字段含义:
    length —— 管理的数据长度。
    type —— 管理的数据类型。
    data —— 数据指针。
    flags —— 标志位,跟具体数据类型有关

    TLV结构

    TLV结构即:Type类型, Lenght长度,Value值;它是一种可变格式;Type和Length的长度固定,一般那是2、4个字节;Value的长度由Length指定;

    在一段TLV结构描述的数据中例如RSA密钥:

    1. V值长度<0x80,L表示数据的长度;
    2. V值长度>=0x80的时候,L为0x8X,X表示的L长度要占用的字节数,X个字节用来表示V的长度;
    3. RSA公钥N的第一个字节如果大于0x80,则需要在公钥值前面补00,这是因为modulus 为一个大整数,最高位为符号位,其为1时,就是负数,所以要在最高位填充0x00以保证不为负。所以公钥TLV应该是:02 81 81 00 [128字节个公钥值];
    4. RSA私钥的N,d,p,q,Dp,Dq,Mp也需要考虑(2)中的第一个字节如果大于0x80的情况;

    DER格式

    接下来按照TLV格式来分析Openssl所生成的der格式的2048位私钥,这里先说明一下pem格式的密钥和der格式的密钥的区别仅仅在于将der格式的密钥进行base64编码之后加上表头和结尾即为pem格式;

    PKCS#1形式私钥的ASN1定义:

    RSAPrivateKey ::= SEQUENCE {
     version Version,
     modulus INTEGER, -- n
     publicExponent INTEGER, -- e
     privateExponent INTEGER, -- d
     prime1 INTEGER, -- p
     prime2 INTEGER, -- q
     exponent1 INTEGER, -- d mod (p-1)
     exponent2 INTEGER, -- d mod (q-1)
     coefficient INTEGER -- (inverse of q) mod p 
    }
    
    

    可见私钥当中包含了n、e、d值,所以理论上可以使用私钥进行加密和解密,而在一些加密锁的厂家为了节省内存,会对私钥进行删减,仅仅保留相关解密的参数;

    私钥的二进制数据按照TLV结构排列如下:

    30 82 04 A2 
        02 01 
            00 
    
        02 82 01 01 
            00 9C B7 68 03 76 DA E7 B6 07 04 07 A7 61 B2 C6 4D C7 42 E3 C5 55 BD 55 43 5D 5E 8D FD 6F B5 17 3B 41 46 3B CD 3D 5D 43 30 E7 08 24 1A EF 79 39 60 2A E8 36 3C 25 72 9D A2 2D B5 A3 6A 97 AA 7F F8 19 B8 1B 8D 64 C9 96 32 ED 14 9A 50 26 89 DE BC A3 71 7B 0A 7C 29 6D 9C 6F 6F 0B 06 C8 37 E6 D5 72 1C 51 CE 3E F7 F7 32 00 D6 D0 47 9F DB F6 D8 F8 45 70 47 EC 48 0C B6 1B 61 30 33 86 D0 DF C9 F6 52 B3 2C 7B DC 1B 2D 41 93 D2 4C F2 AA EC 0F 42 CE EF AE 25 3E D5 70 64 AD DB 2C A0 0A 9B C2 05 B9 C9 4A B1 0E 8B 18 07 98 7B 0F 56 13 5B 4A 8A 90 9E 8F 3C D9 CB 5D B3 2F D8 C7 B2 8F 1A B5 B1 B5 A8 17 F9 BC B9 BA 1A 2A 49 6A 6A 5D 5E A7 95 2A 4E 9F 4E 14 D3 9A 4E B5 72 5D 8E 06 92 DE F0 AB 73 A8 36 F9 3D D9 C2 75 7C 7C FD C2 7A E2 1A 8F A8 36 EB 7D 81 0A F5 59 58 CE CD 19 00 C3 
    
        02 03 
            01 00 01 
    
        02 82 01 00 
            31 56 2C 10 AB 22 4F 40 27 05 45 C3 94 26 4B F7 C0 7B 76 69 71 8C A1 83 0B A9 F0 D9 90 89 5A 3E F5 55 BF 0D E5 FB AE 63 7E D8 39 45 A1 8E 70 59 AE 28 5C AA A2 BF 6A 90 DC 03 0A E7 4B C8 09 71 79 E7 54 05 37 6D 9F 33 79 1F BB 54 F0 4D 07 2A 2B EA 55 E9 FF 1C AB BD 4B F7 91 69 19 2F 40 24 82 40 18 20 EE 01 F2 78 73 7B 2D 26 DF 54 C8 69 95 FF 86 51 9E 39 30 87 44 27 5C 9D 5C 1B F5 D7 88 D4 9D E0 AD 0F 3C B0 A2 EC C8 A6 ED 60 CB DE 44 F9 B7 73 D8 29 4F 38 8C 24 91 29 56 B8 E0 94 0A E2 22 27 5B A4 51 90 BE A9 0E 66 EB A1 5C 68 93 D4 25 64 E3 97 B0 56 E1 9F 07 B6 AD 3F 5E 92 66 BB CC AC 4E 80 46 52 D7 3A 57 0D 52 E5 E9 49 37 62 F7 2E C0 0D C3 92 A6 A6 F6 0F D7 9F 1B 98 3E 20 8E F5 67 ED 19 A9 70 F0 82 F4 73 05 B8 30 01 5E 55 01 64 4E 29 BE 84 0A 38 BD EB F2 27 C1 
    
        02 81 81 
            00 D0 8E EF 5F F7 98 86 28 CC 96 71 53 0A 4D BB 84 02 68 0A E7 19 C6 82 7C 7F E4 F4 44 FB EF 6C 39 33 C1 33 F4 1A 28 72 A6 F3 32 09 6A 3A CD 25 3C A0 C1 28 96 87 2D 52 97 51 D5 9D 63 3A 74 73 D6 13 7B 60 A7 38 F3 84 D3 9D 2B 6E A4 71 DE 65 7F 5A 8F 0D 46 9F 2B F5 B0 64 83 F8 95 56 84 7B BF 04 DF 18 FD 0D DB 2A 55 15 2D 71 54 52 AC BD 19 45 2E 0B 84 AB BD 86 69 AE C0 BC 45 4C 31 4B CD 
    
        02 81 81 
            00 C0 5D 8A 29 17 C5 32 BF 92 B3 94 F1 B1 79 90 3E CE F1 B5 42 BB 4C F4 22 1B CF FB AD 46 92 9B AB 9E 60 73 12 EB 53 84 AC D5 58 7B F7 F7 56 63 FD 3B F1 18 8D 4B 67 BB 98 CB 4A D4 62 B8 5A 08 A0 38 E6 F4 74 7C 56 33 2C 99 38 A5 AB F0 83 C9 06 78 98 18 B9 F8 81 C9 5C 6F E1 82 A1 A1 D5 08 D6 BE 20 90 CA D6 E5 79 F9 DF E1 A7 A2 B0 1E D5 6F F9 3C 68 96 24 29 06 16 22 DA 2A 48 86 F5 8E CF 
    
        02 81 80 
            57 C2 EE 24 1A 12 8A D1 FC 55 8A 56 81 4D 78 8C F2 5E 49 C8 39 E6 78 DE 5F 0B 3F 67 10 05 0E 2B 7C 05 DF 10 E7 39 02 16 12 DC 89 6D B4 54 C3 48 A1 F4 E6 59 81 84 A6 EE 9A 37 23 C5 AF C1 75 45 2E 69 8A A0 93 AC 95 C6 5E AA FA 22 24 F0 8B 11 6E 50 28 2C 01 AB 03 F6 38 35 F8 93 0F 17 2C E3 92 EF 36 9A B6 0B F5 E2 5B C9 05 99 90 38 B4 52 3F F4 42 50 8F DC 6F 05 65 CE 20 EB A0 46 56 39 
    
        02 81 80 
            02 70 6D 33 0E 31 1A EE A0 EE 94 01 E8 8D 31 0E 0A D3 B7 C7 AB D6 52 F6 27 C2 20 5F D7 18 3E CF 13 48 07 CD 82 9C 61 7F 4B 89 3E B1 2B 3A B6 33 DC D1 B6 CC FB DA C9 DF 2B 1C BC CA AF A9 BC 98 43 80 72 33 13 EC 87 E3 95 E1 C9 00 00 21 BB A7 D0 59 A5 5E 9E 4F 0E FD 94 11 98 F5 71 B6 E0 D0 D0 42 5B 73 A6 FB EB EB 06 32 B7 4C 71 CD 42 49 94 30 76 E7 08 78 58 B2 69 28 B9 06 88 67 8E B3 
    
        02 81 80 
            0F 6D 4D 97 25 5A BC 9D F9 B4 4D FF AF 56 09 44 1A D6 CE 8D 27 AA B3 F8 D1 D3 E3 3B B2 77 D4 5A 45 6F DA 62 C3 1D B4 C9 AE 19 84 72 A4 91 A5 F1 5B F3 D6 BC 71 E9 FA 99 BD D5 03 E6 65 78 25 AE CD A8 5B 77 1F 15 60 AC 5F AA 7F C0 29 91 A1 9C 44 91 8B 82 9C 02 4C 4E 73 9A 6D 90 31 44 28 BA ED 5D 7D 1B 6E 4D E2 EB 66 C9 0B 49 FE A5 E7 7E 63 57 D9 BC 67 43 13 1D 26 CF 92 FD 17 74 77 5B 
    
    

    Openssl查看密钥参数如下:

    openssl rsa -in private_pkcs1.pem -text -noout
    
    Private-Key: (2048 bit)
    modulus:
        00:9c:b7:68:03:76:da:e7:b6:07:04:07:a7:61:b2:
        c6:4d:c7:42:e3:c5:55:bd:55:43:5d:5e:8d:fd:6f:
        b5:17:3b:41:46:3b:cd:3d:5d:43:30:e7:08:24:1a:
        ef:79:39:60:2a:e8:36:3c:25:72:9d:a2:2d:b5:a3:
        6a:97:aa:7f:f8:19:b8:1b:8d:64:c9:96:32:ed:14:
        9a:50:26:89:de:bc:a3:71:7b:0a:7c:29:6d:9c:6f:
        6f:0b:06:c8:37:e6:d5:72:1c:51:ce:3e:f7:f7:32:
        00:d6:d0:47:9f:db:f6:d8:f8:45:70:47:ec:48:0c:
        b6:1b:61:30:33:86:d0:df:c9:f6:52:b3:2c:7b:dc:
        1b:2d:41:93:d2:4c:f2:aa:ec:0f:42:ce:ef:ae:25:
        3e:d5:70:64:ad:db:2c:a0:0a:9b:c2:05:b9:c9:4a:
        b1:0e:8b:18:07:98:7b:0f:56:13:5b:4a:8a:90:9e:
        8f:3c:d9:cb:5d:b3:2f:d8:c7:b2:8f:1a:b5:b1:b5:
        a8:17:f9:bc:b9:ba:1a:2a:49:6a:6a:5d:5e:a7:95:
        2a:4e:9f:4e:14:d3:9a:4e:b5:72:5d:8e:06:92:de:
        f0:ab:73:a8:36:f9:3d:d9:c2:75:7c:7c:fd:c2:7a:
        e2:1a:8f:a8:36:eb:7d:81:0a:f5:59:58:ce:cd:19:
        00:c3
    publicExponent: 65537 (0x10001)
    privateExponent:
        31:56:2c:10:ab:22:4f:40:27:05:45:c3:94:26:4b:
        f7:c0:7b:76:69:71:8c:a1:83:0b:a9:f0:d9:90:89:
        5a:3e:f5:55:bf:0d:e5:fb:ae:63:7e:d8:39:45:a1:
        8e:70:59:ae:28:5c:aa:a2:bf:6a:90:dc:03:0a:e7:
        4b:c8:09:71:79:e7:54:05:37:6d:9f:33:79:1f:bb:
        54:f0:4d:07:2a:2b:ea:55:e9:ff:1c:ab:bd:4b:f7:
        91:69:19:2f:40:24:82:40:18:20:ee:01:f2:78:73:
        7b:2d:26:df:54:c8:69:95:ff:86:51:9e:39:30:87:
        44:27:5c:9d:5c:1b:f5:d7:88:d4:9d:e0:ad:0f:3c:
        b0:a2:ec:c8:a6:ed:60:cb:de:44:f9:b7:73:d8:29:
        4f:38:8c:24:91:29:56:b8:e0:94:0a:e2:22:27:5b:
        a4:51:90:be:a9:0e:66:eb:a1:5c:68:93:d4:25:64:
        e3:97:b0:56:e1:9f:07:b6:ad:3f:5e:92:66:bb:cc:
        ac:4e:80:46:52:d7:3a:57:0d:52:e5:e9:49:37:62:
        f7:2e:c0:0d:c3:92:a6:a6:f6:0f:d7:9f:1b:98:3e:
        20:8e:f5:67:ed:19:a9:70:f0:82:f4:73:05:b8:30:
        01:5e:55:01:64:4e:29:be:84:0a:38:bd:eb:f2:27:
        c1
    prime1:
        00:d0:8e:ef:5f:f7:98:86:28:cc:96:71:53:0a:4d:
        bb:84:02:68:0a:e7:19:c6:82:7c:7f:e4:f4:44:fb:
        ef:6c:39:33:c1:33:f4:1a:28:72:a6:f3:32:09:6a:
        3a:cd:25:3c:a0:c1:28:96:87:2d:52:97:51:d5:9d:
        63:3a:74:73:d6:13:7b:60:a7:38:f3:84:d3:9d:2b:
        6e:a4:71:de:65:7f:5a:8f:0d:46:9f:2b:f5:b0:64:
        83:f8:95:56:84:7b:bf:04:df:18:fd:0d:db:2a:55:
        15:2d:71:54:52:ac:bd:19:45:2e:0b:84:ab:bd:86:
        69:ae:c0:bc:45:4c:31:4b:cd
    prime2:
        00:c0:5d:8a:29:17:c5:32:bf:92:b3:94:f1:b1:79:
        90:3e:ce:f1:b5:42:bb:4c:f4:22:1b:cf:fb:ad:46:
        92:9b:ab:9e:60:73:12:eb:53:84:ac:d5:58:7b:f7:
        f7:56:63:fd:3b:f1:18:8d:4b:67:bb:98:cb:4a:d4:
        62:b8:5a:08:a0:38:e6:f4:74:7c:56:33:2c:99:38:
        a5:ab:f0:83:c9:06:78:98:18:b9:f8:81:c9:5c:6f:
        e1:82:a1:a1:d5:08:d6:be:20:90:ca:d6:e5:79:f9:
        df:e1:a7:a2:b0:1e:d5:6f:f9:3c:68:96:24:29:06:
        16:22:da:2a:48:86:f5:8e:cf
    exponent1:
        57:c2:ee:24:1a:12:8a:d1:fc:55:8a:56:81:4d:78:
        8c:f2:5e:49:c8:39:e6:78:de:5f:0b:3f:67:10:05:
        0e:2b:7c:05:df:10:e7:39:02:16:12:dc:89:6d:b4:
        54:c3:48:a1:f4:e6:59:81:84:a6:ee:9a:37:23:c5:
        af:c1:75:45:2e:69:8a:a0:93:ac:95:c6:5e:aa:fa:
        22:24:f0:8b:11:6e:50:28:2c:01:ab:03:f6:38:35:
        f8:93:0f:17:2c:e3:92:ef:36:9a:b6:0b:f5:e2:5b:
        c9:05:99:90:38:b4:52:3f:f4:42:50:8f:dc:6f:05:
        65:ce:20:eb:a0:46:56:39
    exponent2:
        02:70:6d:33:0e:31:1a:ee:a0:ee:94:01:e8:8d:31:
        0e:0a:d3:b7:c7:ab:d6:52:f6:27:c2:20:5f:d7:18:
        3e:cf:13:48:07:cd:82:9c:61:7f:4b:89:3e:b1:2b:
        3a:b6:33:dc:d1:b6:cc:fb:da:c9:df:2b:1c:bc:ca:
        af:a9:bc:98:43:80:72:33:13:ec:87:e3:95:e1:c9:
        00:00:21:bb:a7:d0:59:a5:5e:9e:4f:0e:fd:94:11:
        98:f5:71:b6:e0:d0:d0:42:5b:73:a6:fb:eb:eb:06:
        32:b7:4c:71:cd:42:49:94:30:76:e7:08:78:58:b2:
        69:28:b9:06:88:67:8e:b3
    coefficient:
        0f:6d:4d:97:25:5a:bc:9d:f9:b4:4d:ff:af:56:09:
        44:1a:d6:ce:8d:27:aa:b3:f8:d1:d3:e3:3b:b2:77:
        d4:5a:45:6f:da:62:c3:1d:b4:c9:ae:19:84:72:a4:
        91:a5:f1:5b:f3:d6:bc:71:e9:fa:99:bd:d5:03:e6:
        65:78:25:ae:cd:a8:5b:77:1f:15:60:ac:5f:aa:7f:
        c0:29:91:a1:9c:44:91:8b:82:9c:02:4c:4e:73:9a:
        6d:90:31:44:28:ba:ed:5d:7d:1b:6e:4d:e2:eb:66:
        c9:0b:49:fe:a5:e7:7e:63:57:d9:bc:67:43:13:1d:
        26:cf:92:fd:17:74:77:5b
    
    

    这里我们大致可以看出TLV结构中的Value和上述过程中的各个参数一致,但是需要说明的是Openssl在查看密钥参数时,已经做了处理保证了modulus、p、q之类有符号位的大数不为负数;所以当我们自己根据这各个参数进行拼接der格式时,具体的方法应当参见上述TLV结构说明;

    1. 结构头
    30 82 04 A2   
    

    30 :Type
    04A2: 下面内容总长度,超过了0xFF,所以用两个字节描述,所以第二个字节为82,如果下面总长度没有超过0xFF,只用一个字节可以描述,则为81

    1. 子结构头1
    02 81 81
    

    02:表示asn1_string_st中的type
    81:表示长度大于0x80,同时只用一个字节就可以描述
    81:参数长度

    1. 子结构头2
    02 82 01 00
    

    02:表示asn1_string_st中的type
    82:表示长度大于0xFF,需要用两个字节描述
    0100:参数长度

    1. 子结构头3
    02 03
    

    02:表示asn1_string_st中的type
    03:表示长度是3,小于0x80

    1. 大数补位00
      N,d,p,q,Dp,Dq,Mp这几个参数在Openssl中都是asn1_string_st结构,内部data字段存放相关数据,因此在拼接der格式时,必须先获取这个data字段存放数据的第一个字节,判断大于0x80,则前面补00,此时该子结构头的长度加1

    Openssl常用指令

    1. 生成指定位数私钥,默认为pkcs#1格式
    openssl genrsa -out openssl_rsa_private.pem 2048
    
    1. 从私钥生成公钥,默认为pkcs#8格式
    openssl rsa -in openssl_rsa_private.pem –out openssl_rsa_public.pem -outform PEM –pubout
    
    1. pkcs#1私钥转换为pkcs#8格式
    openssl pkcs8 -topk8 -inform PEM -in openssl_rsa_private.pem -outform pem -nocrypt -out pkcs8.pem
    
    1. pkcs#8格式私钥再转换为pkcs#1格式
    openssl rsa -in pkcs8.pem -out openssl_rsa_private.pem
    
    1. pkcs#8公钥转pkcs#1公钥
    openssl rsa -pubin -in openssl_rsa_public.pem -RSAPublicKey_out
    
    1. pkcs#1公钥转换为pkcs#8公钥
    openssl rsa -RSAPublicKey_in -in pub_pkcs1.pem -pubout
    
    1. pem格式转化为der格式
    //私钥
    openssl rsa -in openssl_rsa_private.pem -out openssl_rsa_private.der -outform der
    
    //公钥
    openssl rsa -in openssl_rsa_public.pem -out openssl_rsa_public.der -pubin -outform der 
    
    
    1. 公钥加密
    //注意最后的填充方式 
    openssl rsautl -encrypt -in encResult.bin -pubin -inkey openssl_rsa_public.pem -out decResult.txt –raw
    
    
    1. 私钥解密
    openssl rsautl -decrypt -in encResult.bin -inkey openssl_rsa_private.pem -out hello.de
    

    相关文章

      网友评论

        本文标题:Openssl库之RSA格式解析

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