I have a tag with the following value: Tag(nr=16, typ=32, cls=0)
What do each of those values mean?
Based on https://en.wikipedia.org/wiki/X.690#Types , I think typ=32 should mean TIME-OF-DAY, but that doesn't make sense in my context.
So what is my context? I'm glad you asked: I'm unpacking an ECDH_SECP256R1 private key created with the following:
>>> import asn1
>>> from Crypto.IO.PKCS8 import unwrap
>>> import binascii
>>> from CryptoMobile.EC import *
>>> ec_B = ECDH_SECP256R1()
>>> ec_B.get_privkey()
b'0\x81\x87\x02\x01\x000\x13\x06\x07*\x86H\xce=\x02\x01\x06\x08*\x86H\xce=\x03\x01\x07\x04m0k\x02\x01\x01\x04 Wj\x80L\t\xc5\xa1oW\xd9\xbbFs{TH\xea\xe1*\x9a\x95\xf6\xe1\xd1\xe1\x9a%\xc8\xb7\xb3~h\xa1D\x03B\x00\x04\xf0T\xear^x\xb6\xa8\xe8\x04T \xf1\xbe\x81\xac\xba\xfdJ\xa10Y_\x0b\xb5^\x140\xaf\xa1S\x14|@\xfaV\x08\x15\x05Cr\xa7\xd1F\xcevq(H\x8a\x8d\xa2\xce\x84\xaa<\x0b>\xf5\xe0\xf1\xed\x9f\x90'
>>> unwrap(ec_B.get_privkey())
('1.2.840.10045.2.1', b'0k\x02\x01\x01\x04 Wj\x80L\t\xc5\xa1oW\xd9\xbbFs{TH\xea\xe1*\x9a\x95\xf6\xe1\xd1\xe1\x9a%\xc8\xb7\xb3~h\xa1D\x03B\x00\x04\xf0T\xear^x\xb6\xa8\xe8\x04T \xf1\xbe\x81\xac\xba\xfdJ\xa10Y_\x0b\xb5^\x140\xaf\xa1S\x14|@\xfaV\x08\x15\x05Cr\xa7\xd1F\xcevq(H\x8a\x8d\xa2\xce\x84\xaa<\x0b>\xf5\xe0\xf1\xed\x9f\x90', b'\x06\x08*\x86H\xce=\x03\x01\x07')
>>>
>>>
>>> decoder = asn1.Decoder()
>>> decoder.start(unwrap(ec_B.get_privkey())[1])
>>> tag, value = decoder.read()
>>> tag
Tag(nr=16, typ=32, cls=0)
>>> value
b'\x02\x01\x01\x04 Wj\x80L\t\xc5\xa1oW\xd9\xbbFs{TH\xea\xe1*\x9a\x95\xf6\xe1\xd1\xe1\x9a%\xc8\xb7\xb3~h\xa1D\x03B\x00\x04\xf0T\xear^x\xb6\xa8\xe8\x04T \xf1\xbe\x81\xac\xba\xfdJ\xa10Y_\x0b\xb5^\x140\xaf\xa1S\x14|@\xfaV\x08\x15\x05Cr\xa7\xd1F\xcevq(H\x8a\x8d\xa2\xce\x84\xaa<\x0b>\xf5\xe0\xf1\xed\x9f\x90'
I'm thinking that tag tells me how to understand the value. Or perhaps Python has already understood the value from the tag? Is this the final decoded value?
>>> print(binascii.hexlify(value))
b'0201010420576a804c09c5a16f57d9bb46737b5448eae12a9a95f6e1d1e19a25c8b7b37e68a14403420004f054ea725e78b6a8e8045420f1be81acbafd4aa130595f0bb55e1430afa153147c40fa560815054372a7d146ce767128488a8da2ce84aa3c0b3ef5e0f1ed9f90'
Or do I have to use knowledge of the tag to further decode that?
Note that, in ASN.1, the tag has no meaning... it is just used to encode and decode data (and only in BER, DER, CER encoding rules)
To have the meaning of the data, you always need the ASN.1 specification ( ECPrivateKey
in @Crypt32 answer)
The all concept of encoding and decoding BER is explained in document x.690
When you encode a tag (see 8.1.2 in the x.690 doc), you need 3 pieces of information:
Let's take ECPrivateKey
...
So, back to your question:
Tag(nr=16, typ=32, cls=0)
Note that the names are from the tool you are using and not ASN.1 vocabulary
EDIT: it is actually well summarized in the link you provided https://en.wikipedia.org/wiki/X.690#Types
Go to https://asn1.io/asn1playground/ and compile following specification...
Example DEFINITIONS EXPLICIT TAGS ::=
BEGIN
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
privateKey OCTET STRING,
-- parameters [0] ECParameters {{ NamedCurve }} OPTIONAL, --
publicKey [1] BIT STRING OPTIONAL
}
END
Decode following value (I just put 306B before your value)... which means a SEQUENCE of 107 bytes
306B0201010420576a804c09c5a16f57d9bb46737b5448eae12a9a95f6e1d1e19a25c8b7b37e68a14403420004f054ea725e78b6a8e8045420f1be81acbafd4aa130595f0bb55e1430afa153147c40fa560815054372a7d146ce767128488a8da2ce84aa3c0b3ef5e0f1ed9f90
You see that your value is a sequence of version, privateKey and publicKey (the optional parameters is absent)
ECPrivateKey SEQUENCE: tag = [UNIVERSAL 16] constructed; length = 107
version INTEGER: tag = [UNIVERSAL 2] primitive; length = 1
1
privateKey OCTET STRING: tag = [UNIVERSAL 4] primitive; length = 32
0x576a804c09c5a16f57d9bb46737b5448ea ...
publicKey : tag = [1] constructed; length = 68
BIT STRING: tag = [UNIVERSAL 3] primitive; length = 66
0x0004f054ea725e78b6a8e8045420f1be81 ...
Successfully decoded 109 bytes.
rec1value ECPrivateKey ::=
{
version ecPrivkeyVer1,
privateKey '576A804C09C5A16F57D9BB46737B5448EA ...'H,
publicKey '00000100 11110000 01010100 11101010 011 ...'B
}
Tag 16 is SEQUENCE
or SEQUENCE OF
. typ=32
suggests that bit 6 is set to 1, so SEQUENCE is in constructed form. In fact, in cryptography messages, SEQUENCE is always used in constructed form. I have no idea what cls=0
means (I'm not familiar with Python).
SEQUENCE
is a struct with arbitrary fields. SEQUENCE OF
is an ordered array of elements of same type (primitive or constructed). Exact type ( SEQUENCE
of SEQUENCE OF
) is determined by ASN.1 module definition.
value
in your case is a valid ECPrivateKey
(as per RFC 5915 ) struct as defined below:
ECPrivateKey ::= SEQUENCE {
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1),
privateKey OCTET STRING,
parameters [0] ECParameters {{ NamedCurve }} OPTIONAL,
publicKey [1] BIT STRING OPTIONAL
}
and the dump in ASN.1 Editor:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.