我正在研究如何使用RSA加密。我了解所有内容,但不了解私钥的格式。

在phpseclib(PHP中的RSA)中,您可以导入私钥(private.key格式),并且在密钥文件中有类似以下内容的文本this:

-----BEGIN RSA PRIVATE KEY-----
MIIBOQIBAAJBAIOLepgdqXrM07O4dV/nJ5gSA12jcjBeBXK5mZO7Gc778HuvhJi+
RvqhSi82EuN9sHPx1iQqaCuXuS1vpuqvYiUCAwEAAQJATRDbCuFd2EbFxGXNxhjL
loj/Fc3a6UE8GeFoeydDUIJjWifbCAQsptSPIT5vhcudZgWEMDSXrIn79nXvyPy5
BQIhAPU+XwrLGy0Hd4Roug+9IRMrlu0gtSvTJRWQ/b7m0fbfAiEAiVB7bUMynZf4
SwVJ8NAF4AikBmYxOJPUxnPjEp8D23sCIA3ZcNqWL7myQ0CZ/W/oGVcQzhwkDbck
3GJEZuAB/vd3AiASmnvOZs9BuKgkCdhlrtlM6/7E+y1p++VU6bh2+mI8ZwIgf4Qh
u+zYCJfIjtJJpH1lHZW+A60iThKtezaCk7FiAC4= 
-----END RSA PRIVATE KEY-----


但是当我用Base64对其进行解码,然后将其转换为十进制时,它只是一个数字...
我认为您同时需要$ p $和$ q $!我的问题:

如果我掷骰子(0和1)1024次并找到最接近的素数,那将是我的$ p $,我将再次执行此过程,所以我会得到$ q $ ,但是如何将这些数字转换为private.key格式?和有什么区别?

评论

请注意:您在互联网上发布了私钥。现在它不安全了,您必须生成一个新的。

另请参阅RSA私钥中保存了哪些数据?

#1 楼

将该键复制/粘贴到http://phpseclib.sourceforge.net/x509/asn1parse.php中,您将看到其中包含几个不同的整数。 $ p $在那里,$ q $在那里,指数和其他几个整数也可以利用中国余数定理来加快处理速度。

密钥使用DER编码并得出语义通过ASN.1。下面的URL进行了详细说明:

http://tools.ietf.org/html/rfc3447#appendix-C

引用我了解RSA加密的数学原理: 〜/ .ssh中的文件与理论有关吗?:


DER3编码的字符串的ASN.1语法在RFC3447(又名PKCS1)中进行了描述:

  Version ::= INTEGER { two-prime(0), multi(1) }
      (CONSTRAINED BY
      {-- version must be multi if otherPrimeInfos present --})

  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
      otherPrimeInfos   OtherPrimeInfos OPTIONAL
  }


DER编码使用标记长度值符号。因此,这里有一个示例
私钥:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQCqGKukO1De7zhZj6+H0qtjTkVxwTCpvKe4eCZ0FPqri0cb2JZfXJ/DgYSF6vUp
wmJG8wVQZKjeGcjDOL5UlsuusFncCzWBQ7RKNUSesmQRMSGkVb1/3j+skZ6UtW+5u09lHNsj6tQ5
1s1SPrCBkedbNf0Tp0GbMJDyR4e9T04ZZwIDAQABAoGAFijko56+qGyN8M0RVyaRAXz++xTqHBLh
3tx4VgMtrQ+WEgCjhoTwo23KMBAuJGSYnRmoBZM3lMfTKevIkAidPExvYCdm5dYq3XToLkkLv5L2
pIIVOFMDG+KESnAFV7l2c+cnzRMW0+b6f8mR1CJzZuxVLL6Q02fvLi55/mbSYxECQQDeAw6fiIQX
GukBI4eMZZt4nscy2o12KyYner3VpoeE+Np2q+Z3pvAMd/aNzQ/W9WaI+NRfcxUJrmfPwIGm63il
AkEAxCL5HQb2bQr4ByorcMWm/hEP2MZzROV73yF41hPsRC9m66KrheO9HPTJuo3/9s5p+sqGxOlF
L0NDt4SkosjgGwJAFklyR1uZ/wPJjj611cdBcztlPdqoxssQGnh85BzCj/u3WqBpE2vjvyyvyI5k
X6zk7S0ljKtt2jny2+00VsBerQJBAJGC1Mg5Oydo5NwD6BiROrPxGo2bpTbu/fhrT8ebHkTz2epl
U9VQQSQzY1oZMVX8i1m5WUTLPz2yLJIBQVdXqhMCQBGoiuSoSjafUhV7i1cEGpb88h5NBYZzWXGZ
37sJ5QsW+sJyoNde3xH8vdXhzU7eT82D6X/scw9RZz+/6rCJ4p0=
-----END RSA PRIVATE KEY-----


这是十六进制编码:

3082025c02010002818100aa18aba43b50deef38598faf87d2ab634e4571c130a9bca7b878267414
faab8b471bd8965f5c9fc3818485eaf529c26246f3055064a8de19c8c338be5496cbaeb059dc0b35
8143b44a35449eb264113121a455bd7fde3fac919e94b56fb9bb4f651cdb23ead439d6cd523eb081
91e75b35fd13a7419b3090f24787bd4f4e196702030100010281801628e4a39ebea86c8df0cd1157
2691017cfefb14ea1c12e1dedc7856032dad0f961200a38684f0a36dca30102e2464989d19a80593
3794c7d329ebc890089d3c4c6f602766e5d62add74e82e490bbf92f6a482153853031be2844a7005
57b97673e727cd1316d3e6fa7fc991d4227366ec552cbe90d367ef2e2e79fe66d26311024100de03
0e9f8884171ae90123878c659b789ec732da8d762b26277abdd5a68784f8da76abe677a6f00c77f6
8dcd0fd6f56688f8d45f731509ae67cfc081a6eb78a5024100c422f91d06f66d0af8072a2b70c5a6
fe110fd8c67344e57bdf2178d613ec442f66eba2ab85e3bd1cf4c9ba8dfff6ce69faca86c4e9452f
4343b784a4a2c8e01b0240164972475b99ff03c98e3eb5d5c741733b653ddaa8c6cb101a787ce41c
c28ffbb75aa069136be3bf2cafc88e645face4ed2d258cab6dda39f2dbed3456c05ead0241009182
d4c8393b2768e4dc03e818913ab3f11a8d9ba536eefdf86b4fc79b1e44f3d9ea6553d55041243363
5a193155fc8b59b95944cb3f3db22c9201415757aa13024011a88ae4a84a369f52157b8b57041a96
fcf21e4d058673597199dfbb09e50b16fac272a0d75edf11fcbdd5e1cd4ede4fcd83e97fec730f51
673fbfeab089e29d


30是因为它是SEQUENCE标签。 82025c表示
长度。第一个字节表示长度为“长格式”(82和80),而后两个字节表示长度(82和7F)。因此,
SEQUENCE的实际长度为025c。因此,在此之后就是值。

然后进入版本。 02是int类型,01是标记长度
,00是值。即。它是一个双主键,而不是
多主键。

有关可分辨编码规则的更多信息。

试图理解ASN.1是为了理解RSA私钥的格式,
变得非常复杂且很多。
是不必要的。对于X.509,它变得更加必要,但是RSA密钥
并没有像X.509证书那样复杂,在格式化方面。

希望对您有所帮助!


评论


$ \ begingroup $
评论不用于扩展讨论;此对话已移至聊天。
$ \ endgroup $
– e-sushi
17年6月9日在23:36

$ \ begingroup $
另一个有助于理解结构的有用的ASN.1解码器:lapo.it/asn1js
$ \ endgroup $
– RetoHöhener
19/12/24在11:14

$ \ begingroup $
将私钥粘贴到不受HTTPS保护的站点中,却不知道使用密钥在后台进行的操作似乎是一个坏主意!
$ \ endgroup $
–mc1arke
20 Mar 11 '20 at 12:53

#2 楼

正确的是,给定的私钥没有编码单个整数,并且包含两个质数$ p $和$ q $。更准确地说,该Base64数据编码了一个字节字符串,它是按照PKCS#1v2.2附录A.1.2(可能仅限于版本0)按照ASN.1 DER-TLV(因此是BER-TLV)编码的RSAPrivateKey。它解码为:




30用于序列的ASN.1标签,一个BER-TLV标签(应用程序类,构造的编码,标签号0)

82 01 39作为前缀的长度加上两个字节,即0x139 = 313(紧随其后的字节数) (通用类,原始编码,标记号2)

02在1个字节上编码的长度,为0x01 = 1



01版本0,含义,带有2个质数的RSA私钥。



00 int的ASN.1标签


02在一个字节上编码的长度,为0x41 = 65

41公共模数$ n $(大端,最左边的位是符号)




00 83 8B 7A 98 1D A9 7A CC D3 B3 B8 75 5F E7 27 98 12 03 5D A3 72 30 5E 05 72 B9 99 93 BB 19 CE FB F0 7B AF 84 98 BE 46 FA A1 4A 2F 36 12 E3 7D B0 73 F1 D6 24 2A 68 2B 97 B9 2D 6F A6 EA AF 62 25 int的ASN.1标签


02编码在一个字节上的长度,为0x03 = 3



03公共指数$ e $(big-endian,最左边的位是符号)



01 00 01 int的ASN.1标签


q 4312079q在1个字节上编码的长度,为0x40 = 64




02私有指数$ d $(大端,最左边的位是符号)



40用于int的ASN.1标签


4D 10 DB 0A E1 5D D8 46 C5 C4 65 CD C6 18 CB 96 88 FF 15 CD DA E9 41 3C 19 E1 68 7B 27 43 50 82 63 5A 27 DB 08 04 2C A6 D4 8F 21 3E 6F 85 CB 9D 66 05 84 30 34 97 AC 89 FB F6 75 EF C8 FC B9 05编码在一个字节上的长度,为0x21 = 33



02秘密素数$ p $(大端,最左边的位是符号)



21 int的ASN.1标签


00 F5 3E 5F 0A CB 1B 2D 07 77 84 68 BA 0F BD 21 13 2B 96 ED 20 B5 2B D3 25 15 90 FD BE E6 D1 F6 DF编码在一个字节上的长度,为0x21 = 33




02秘密素数$ q $(大端,最左位是符号)




21用于int的ASN.1标签


00 89 50 7B 6D 43 32 9D 97 F8 4B 05 49 F0 D0 05 E0 08 A4 06 66 31 38 93 D4 C6 73 E3 12 9F 03 DB 7B在1个字节上编码的长度,为0x20 = 32



02 $ dp = d \ bmod(p-1)$(大端,最左边的位是符号)



20用于int的ASN.1标签


0D D9 70 DA 96 2F B9 B2 43 40 99 FD 6F E8 19 57 10 CE 1C 24 0D B7 24 DC 62 44 66 E0 01 FE F7 77编码在一个字节上的长度,0x20 = 32



02 $ dq = d \ bmod(q-1)$(大端,最左位是符号)



用于int的20 ASN.1标签


12 9A 7B CE 66 CF 41 B8 A8 24 09 D8 65 AE D9 4C EB FE C4 FB 2D 69 FB E5 54 E9 B8 76 FA 62 3C 67编码在一个字节上的长度,为0x20 = 32 \ text {inv} = q ^ {-1} \ bmod p $(大端,最左端是符号)






因此,该私钥有:


$ N $ = 6889562268374622799957651484276189567066573692163081374402850932375514118031048420110853972747558241305562483958233191802399592639320405757333978594894373
$ E $ = 65537
$ D $ = 4036265671212347870735218712159303880670782869380678233214786480134242711167668040594757438422211656546040377235338723652323162649874081271989898105895173
$ P $ = 110926848377808511478526072563819593239744031998335766139683653481372583065311
$ Q $ = 62109059881601353504240950986730444628975000449359215027377545384004575026043
$ DP $ = 6264251733315063261699879374379301990940883202249731761950794231267222026103
$ DQ $ = 8414580201851449070969916288679366126930879182597013446268294634551118019687
$ Q_ \文本{INV} $ = 57677188406707620788831013172875873422122983590947547357547002213122938372142

如预期,这些值将验证:


$ n = p \ cdot q $
$ e \ cdot d \ equiv 1 \ pmod { \ operatorname {lcm}(p-1,q-1)} $
$ dp = e ^ {-1} \ bmod(p-1)= d \ bmod(p-1)$
$ dq = e ^ {-1} \ bmod(q-1)= d \ bmod(q-1)$
$ q_ \ text {inv} = q ^ {-1} \ bmod p $

公共模数$ n $是512位,太小了,不足以保证安全。


如果一个人使用1024个骰子投掷$ p $和$ q $,四舍五入到最接近的较低质数,则$ p $和$ q $大约(最多)约1024位,因此公共模数$ n $大约2048位,这很安全。 $ p $和$ q $具有绝对的优势。

习惯上并建议确保$ n $具有正好$ k $位,而$ k $是2的幂的倍数至少要达到64,并朝着这个目标选择$ p $和$ q $高于$ 2 ^ {(k-1)/ 2} $。

选择$ e = 2是惯例且无可争议的^ {16} + 1 = 65537 $,朝着这个目标选择$ p $和$ q $,使得$ p \ not \ equiv1 \ pmod {65537} $和$ q \ not \ equiv1 \ pmod {65537} $ 。

然后,一个


计算$ n $,$ d $,$ dp $,$ dq $,$ q_ \ text {inv} $, $ d $;对于$ d $,在其他选项中,可以


计算$ d = e ^ {-1} \ bmod((p-1)\ cdot(q-1))$就像上面的私钥一样,
为稍小的$ d $计算$ d = e ^ {-1} \ bmod(\ operatorname {lcm}(p-1,q-1))$ />从$ dp $和$ dq $中构建$ d $;


按照上述PKCS#1v2附录A.1.2,按照ASN.1 DER-TLV编码私钥; 添加0220分隔符;
酌情添加换行符(至少包括每个分隔符之前和之后,除非文件开头不需要换行符)。

从示例中归纳到ASN.1 DER-TLV时,容易遗漏规则:


长度编码(在RSA的情况下,所有长度通常在[1..0xFFFF]范围内,但某些实现具有较小的大小限制)


从0到0x7F的任何长度都在7F 84 21 BB EC D8 08 97 C8 8E D2 49 A4 7D 65 1D 95 BE 03 AD 22 4E 12 AD 7B 36 82 93 B1 62 00 2E中编码为一个字节。-----BEGIN RSA PRIVATE KEY-----;
长度不超过0xFF的任何更高长度都被编码为前缀-----END RSA PRIVATE KEY-----和一个字节;
任何长至0xFFFF的较大长度都编码为前缀00和两个字节;
任何长至0xFFFFFF的较大长度都编码为前缀7F和三个字节;直到0xFFFFFFFF的任何更大长度都被编码为前缀81和四个字节;
该规则适用于更大的长度,但是某些标准(包括ISO / IEC 7816-4:2013,附录E.2)明确排除了这些长度。


非负整数的字节表示形式必须是最短的big-endian字节表示形式,并具有最左边的符号位;因此:


它从一个范围为82的字节开始。.83;
如果第一个字节为84,则下一个字节(如果存在)必须在范围内00 .. 7F




评论


$ \ begingroup $
难道不是每一卷6面公平的骰子都会为每个数字贡献$ \ log_2(6)\大约2.6 $位,或者在1024卷之后大约贡献2647位?
$ \ endgroup $
–neirbowj
17年7月29日在14:13

#3 楼

总结一下答案,这里是有关(至少在Linux上)使用openssl查看此类密钥内容的最简单方法的说明:

$ openssl rsa -in test.key -text
Private-Key: (512 bit)
modulus:
    00:83:8b:7a:98:1d:a9:7a:cc:d3:b3:b8:75:5f:e7:
    27:98:12:03:5d:a3:72:30:5e:05:72:b9:99:93:bb:
    19:ce:fb:f0:7b:af:84:98:be:46:fa:a1:4a:2f:36:
    12:e3:7d:b0:73:f1:d6:24:2a:68:2b:97:b9:2d:6f:
    a6:ea:af:62:25
publicExponent: 65537 (0x10001)
privateExponent:
    4d:10:db:0a:e1:5d:d8:46:c5:c4:65:cd:c6:18:cb:
    96:88:ff:15:cd:da:e9:41:3c:19:e1:68:7b:27:43:
    50:82:63:5a:27:db:08:04:2c:a6:d4:8f:21:3e:6f:
    85:cb:9d:66:05:84:30:34:97:ac:89:fb:f6:75:ef:
    c8:fc:b9:05
prime1:
    00:f5:3e:5f:0a:cb:1b:2d:07:77:84:68:ba:0f:bd:
    21:13:2b:96:ed:20:b5:2b:d3:25:15:90:fd:be:e6:
    d1:f6:df
prime2:
    00:89:50:7b:6d:43:32:9d:97:f8:4b:05:49:f0:d0:
    05:e0:08:a4:06:66:31:38:93:d4:c6:73:e3:12:9f:
    03:db:7b
exponent1:
    0d:d9:70:da:96:2f:b9:b2:43:40:99:fd:6f:e8:19:
    57:10:ce:1c:24:0d:b7:24:dc:62:44:66:e0:01:fe:
    f7:77
exponent2:
    12:9a:7b:ce:66:cf:41:b8:a8:24:09:d8:65:ae:d9:
    4c:eb:fe:c4:fb:2d:69:fb:e5:54:e9:b8:76:fa:62:
    3c:67
coefficient:
    7f:84:21:bb:ec:d8:08:97:c8:8e:d2:49:a4:7d:65:
    1d:95:be:03:ad:22:4e:12:ad:7b:36:82:93:b1:62:
    00:2e


如果只有公众RSA密钥-只需将-pubin标志添加到openssl。

评论


$ \ begingroup $
为了回答您的最后一个问题,我可以共享一个Python脚本:pastie.org/9808687,尽管我不确定这是否是stackexchange的最佳方法。
$ \ endgroup $
–分形
2015年1月1日在22:26



#4 楼

那么,
证书二进制海报第1部分和第2部分中的精美图片又如何呢?我相信它们在这种情况下会很有用。

#5 楼

实际上,Base64字符串不仅包含私钥,还包含带有附加信息的特定数据结构。特别是,您的数据包含一个RSAPrivateKey对象,该对象包含多个值,包括质数p和q。您可以在此处看到该对象的描述。