如何从 pyasn1 对象中恢复衬底?

How to recover the substrate from a pyasn1 object?

我有一个复杂的嵌套 ASN.1 结构作为字节。我想找到该结构中的所有 T61String(比如说), 原始字节编码。这在 pyasn1 中可行吗?

到目前为止,我只知道如何在 BER 解码的 Python 对象中定位 T61Strings(或其他)。我可以重新编码每一个,但不能保证重新编码的值与原始值匹配。这里有一些加密,因此对这些字节值很挑剔。

如果我能做 decoded_object.get_substrate() 或类似的事情,我会被分类。

想法?谢谢


更新:Ilya Etingof 的回答似乎很有效。

In [61]: class X(pyasn1.codec.ber.decoder.Decoder):
    ...:     def __call__(self,*v,**kw):
    ...:         parsed,remainder = pyasn1.codec.ber.decoder.Decoder.__call__(self,*v,**kw)
    ...:         parsed._substrate = v[0][:len(v[0])-len(remainder)]
    ...:         return parsed,remainder
    ...:     

In [62]: decode = X(pyasn1.codec.ber.decoder.tagMap,pyasn1.codec.ber.decoder.typeMap)

In [63]: tmp = decode(b'\x30\x05\x02\x01\x7f\x05\x00')[0]

In [64]: tmp._substrate.encode('hex')
Out[64]: '300502017f0500'

In [65]: tmp[0]._substrate.encode('hex')
Out[65]: '02017f'

In [66]: tmp[1]._substrate.encode('hex')
Out[66]: '0500'

In [67]: 

是BER,不是DER?加密应用程序倾向于使用 DER,因为它很稳定。如果它是 DER,您应该能够安全地重新编码一旦解码的项目并获得相同的结果。

pyasn1 中没有允许您将底物片段与解码对象匹配的内置功能。但是您可以通过覆盖 Decoder.call() 方法并记下它的 substrate + length 参数来模拟它,以查看正在解码的内容和覆盖的 [=12] 的 return 值=] 方法是你观察到的基板产生的物体。

请记住,解码过程是递归的,因此您会看到终端(标量)和包含许多其他对象的容器对象。