使用pyasn1正确实现ASN1结构

时间:2016-09-25 17:46:32

标签: python python-3.x pyasn1

我是ASN1的新手,想要使用pyasn1

实现此结构
   ECPrivateKey ::= SEQUENCE {
   version        INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
   privateKey     OCTET STRING,
   parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
   publicKey  [1] BIT STRING OPTIONAL
   }

这是我正在使用的代码

from pyasn1.type import univ, namedtype, tag
class ZKey(univ.Sequence):
   componentType = namedtype.NamedTypes(
   namedtype.NamedType('id', univ.Integer()),
   namedtype.NamedType('priv', univ.OctetString()),
   namedtype.OptionalNamedType(
   'ECParam',
   univ.ObjectIdentifier().subtype(
     implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
      )
    ),
    namedtype.OptionalNamedType(
   'pub', 
   univ.BitString().subtype(
     implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)
   )))

在使用此序列进行编码时,我得到结果like,当我希望结构类似this时。我错过了什么?提前谢谢

1 个答案:

答案 0 :(得分:0)

我想在你正在使用的ASN.1模块中,EXPLICIT标记模式是默认模式。所以在你的pyasn1代码中你也应该使用显式标记。

这是稍微固定的代码,可以按你的意愿工作:

from pyasn1.type import univ, namedtype, tag
from pyasn1.codec.der.encoder import encode
import base64

class ZKey(univ.Sequence):
   componentType = namedtype.NamedTypes(
       namedtype.NamedType('id', univ.Integer()),
       namedtype.NamedType('priv', univ.OctetString()),
       namedtype.OptionalNamedType(
           'ECParam',
           univ.ObjectIdentifier().subtype(
               explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)
           )
       ),
       namedtype.OptionalNamedType(
           'pub', 
           univ.BitString().subtype(
               explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)
           )
       )
   )

zKey = ZKey()
zKey['id'] = 123
zKey['priv'] = 'foo bar'
zKey['ECParam'] = '1.3.6.1'
zKey['pub'] = [1,0,1,1]

substrate = encode(zKey)

print(base64.encodebytes(substrate))