使用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
那为什么第一种方式不起作用呢?
答案 0 :(得分:1)
这些版本正式属于不同类型,并且它们具有不同的BER标记。 rfc2459.Version是普通的INTEGER:
class Version(univ.Integer):
namedValues = namedval.NamedValues(('v1', 0), ('v2', 1), ('v3', 2))
而rfc2459.TBSCertificate的'version'字段SEQUENCE包含Version的子类,它是通过附加标记定义的:
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')自动强制转换为Version子类型。
它们的有效载荷(例如0)确实比较相等,即使对于不同类型,有时也是可能的。考虑:
>>> float(0) == int(0)
True
>>> float == int
False
例如。
回答你的问题:我认为正确的方法是依靠“强制”。这将保证标签/类型的正确性,并将根据目标类型约束(例如值范围,大小等)验证初始化程序。因此,您最终会得到完全兼容的ASN.1结构实例。