如何使用Python gdata.tlslite.utils.ASN1Parser 获取指数和模数?

0 投票
1 回答
561 浏览
提问于 2025-04-17 07:23

我想做的是用Python GAE读取一些PEM格式的公钥。

但是RSAKey模块只支持解析私钥,不支持公钥。

如果我能从PEM中提取出模数和指数,那就可以继续了。

我用openssl的asn1parse工具查看了一下我将要使用的典型PEM格式,找到了里面的BIT STRING部分。

不过,我还搞不清楚怎么用gdata的ASN1Parser来找到这些信息。

比如说,openssl的输出是这样的:

openssl asn1parse -i -in test.pem
 0:d=0  hl=3 l= 159 cons: SEQUENCE          
 3:d=1  hl=2 l=  13 cons:  SEQUENCE          
 5:d=2  hl=2 l=   9 prim:   OBJECT            :rsaEncryption
16:d=2  hl=2 l=   0 prim:   NULL              
18:d=1  hl=3 l= 141 prim:  BIT STRING

然后深入查看后,我可以看到RSA的模数和指数:

openssl asn1parse -strparse 18 -i -in test.pem 
  0:d=0  hl=3 l= 137 cons: SEQUENCE          
  3:d=1  hl=3 l= 129 prim:  INTEGER           :09C7A8007111B2B...
135:d=1  hl=2 l=   3 prim:  INTEGER           :010001

如果我把这个PEM格式的内容放到Python的bytes中,我该怎么找到正确的部分来获取这些值呢?

asn1 = ASN1Parser(bytes)
modulus = asn1.getChild(1).getChild(0).value
exponent = asn1.getChild(1).getChild(1).value
binascii.hexlify(modulus)

或者说,我该怎么做?我搞不清楚需要查看哪个层级等等。我也不是很明白自己在做什么……用hexlify我能看到里面的值,但总是(在调整子元素和深度时)前面有多余的东西,或者显示的数字不完整,跟openssl的输出不一样。

1 个回答

0

我对tlslite进行了修改,让它可以实现你所说的功能……这里有一段代码片段,希望能帮到你。“bytes”是经过DER编码的公钥。

我觉得你遇到的问题可能是因为某些密钥可能有“填充”。填充的长度是负载的第一个字节。你需要跳过这些填充字节,以及相应数量的填充字节。

@staticmethod
def parseDERPublicKey(bytes):
    a = ASN1Parser(bytes)
    b = a.getChild(1)
    padding = b.value[1]
    # TODO: I am assuming padding is 0, this is wrong.
    #       Skip the padding as well.
    c = b.value[1:] # get the mod/exp portion after the padding
    d = ASN1Parser(c)

    modulus = bytesToNumber(d.getChild(0).value)
    exponent = bytesToNumber(d.getChild(1).value)

撰写回答