1

我在使用 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

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

4

1 回答 1

1

这些版本正式属于不同的类型,并且具有不同的 BER 标签。rfc2459.Version 是纯整数:

class Version(univ.Integer):
    namedValues = namedval.NamedValues(('v1', 0), ('v2', 1), ('v3', 2))

而 rfc2459.TBSCertificate SEQUENCE 的 'version' 字段包含通过附加标记定义的 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 结构的实例。

于 2015-07-17T20:18:45.287 回答