对象标识符转换 ASN1

Object Identifier conversion ASN1

我正在尝试在 Python 中实现 ASN1 的自定义对象标识符,这些是示例测试用例。

asn1_objectidentifier([1,2])
asn1_objectidentifier([1,2,840])
asn1_objectidentifier([1,2,840,5,1000000])
asn1_objectidentifier([1,2,840,5,127,128,129])

我无法做到的是以 128 为基数对值 3 ... 值 n 进行编码。 到目前为止,这是我的代码

def asn1_objectidentifier(oid):
    first_octet = 40 * oid[0] + oid[1]
    rest = ""
    length = 1
    for v in range(2, len(oid)):
       if oid[v] < 127:
          rest += chr(oid[v])
          length += 1
       else:
          rem = oid[v] / 128
          first = (rem * 128) ^ 1
          second = (oid[v] - first) * 128 ^ 0
          rest += int_to_bytestring(first)
          rest += int_to_bytestring(second)
          length += 2 

    rest = chr(first_octet) + rest
    return chr(0x06) + chr(length) + rest

下面是对非负整数进行 base 128 编码的方法:

def base128_encode(n): # int/long to byte string
    if n > 0:
        arr = []
        while n:
            n, rem = divmod(n, 128)
            arr.append(chr(rem))
        return ''.join(reversed(arr))
    elif n == 0:
        return '\x00'
    else:
        raise ValueError

print [ord(c) for c in base128_encode(840)]  # --> [6, 72]

这篇优秀的文章 A Layman's Guide to a Subset of ASN.1, BER, and DER 对此进行了一些详细的描述,并且——最有价值的是——给出了许多很好的测试用例和边缘用例。

顺便说一句:该文档在网络上似乎没有规范的主页。以上是link对CiteseerX的参考资料;存在其他 PDF;和 HTML versions.