Python 设置组件时pyasn1和奇怪的不匹配

Python 设置组件时pyasn1和奇怪的不匹配,python,asn.1,pyasn1,Python,Asn.1,Pyasn1,在使用pyasn1设置组件时,我遇到了一个奇怪的问题。我构造并清空证书,并将要签名的证书放入其中: empty = rfc2459.Certificate() empty['tbsCertificate'] = rfc2459.TBSCertificate() 现在我想设置一个版本,该版本在实际版本对象中失败,但通过自动创建一个类型来工作: empty['tbsCertificate']['version'] = rfc2459.Version('v3') # PyAsn1Error: Com

在使用pyasn1设置组件时,我遇到了一个奇怪的问题。我构造并清空证书,并将要签名的证书放入其中:

empty = rfc2459.Certificate()
empty['tbsCertificate'] = rfc2459.TBSCertificate()
现在我想设置一个版本,该版本在实际版本对象中失败,但通过自动创建一个类型来工作:

empty['tbsCertificate']['version'] = rfc2459.Version('v3')
# PyAsn1Error: Component type error Version('v1') vs Version('v3')

empty['tbsCertificate']['version'] = 'v3'
# works
这很奇怪,因为这两个比较相等:

empty['tbsCertificate']['version'] == rfc2459.Version('v3')
# True

那么为什么第一种方法不起作用呢?

这些版本在形式上属于不同的类型,它们有不同的BER标签。rfc2459。版本为纯整数:

class Version(univ.Integer):
    namedValues = namedval.NamedValues(('v1', 0), ('v2', 1), ('v3', 2))
而rfc2459.TBSCertificate序列的“版本”字段包含通过附加标记定义的版本子类:

class TBSCertificate(univ.Sequence):
    componentType = namedtype.NamedTypes(
        namedtype.DefaultedNamedType('version',Version('v1').subtype(
            explicitTag=tag.Tag(
                tag.tagClassContext, tag.tagFormatSimple, 0)
            )
        )...
这就是为什么不能将Version对象放入TBSCertificate['Version']。如果可以,这将正式更改TBSCertificate数据类型及其BER表示

同时,TBSCertificate['version']='v1'由于Python字符串'v1'通过其命名值(例如'v1')自动强制到版本子类型中而起作用

它们的有效载荷(例如0)确实比较相等,这有时甚至对于不同的类型也是可能的。考虑:

>>> float(0) == int(0)
True
>>> float == int
False
比如说

回答你的问题:我认为正确的方法是依靠“胁迫”。这将保证标记/类型的正确性,并根据目标类型约束(例如值范围、大小等)验证初始值设定器。因此,您最终得到了完全兼容的ASN.1结构实例。

那么在这种情况下,“正确的方法”是什么?我应该依靠强制手段吗?或者我应该做些更有趣的事?我会选择“强迫”。刚刚更新了原始答案。