本文将主要描述如何使用asn1解析LIF文件、RAC文件、RAU文件,并以LIF文件作为例子。
python3
还记得LIF文件里那段base64编码的内容吗?这段内容在base64解码后还需要经过一次循环解扰才能得到asn1数据,循环解扰的参数来自LIF文件的TimeStamp字段。此处以网上收集的一份LIF文件(Terra2314.WibuCmLIF)为例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
>>>
import
base64
>>>
import
struct
>>> lif
=
"""UZ2c7xT77/9BygbMO0cf8CM9VG1gdIywuAHhAjqn9rIxvyeP15rvdGjLGEzcaxYhANuJX1np0X25fTEyK8X3CU5r/f2NaEUPqq8g
gwLb0AKenTv2/d6Q9njQExlKvhwHFDQXoPLg0Ak7fc/8GhzZu8Pxq0biHmg82ToBYI4WTTdDENQNuFzzSwiqabadsq163iKfuVIb
7qg5DAIoihMb1NHNSRYypkIM6cmZbFoWh4mBFgN5Al0/H5n3oDUqJhq1MY4t39JouPhJ0EXW3J6vEsneum6mnMROyJPNfcrFx9SR
tjeRZrB1crnOk2Bbcm7cQMiDOEIYKipYJw34YHRf5fCKRg5Ojhnoi2Q7bbis0ZAjBadl4a90ert/tGxUuKgvV2wn//q4KYxq1Cpx
6xvENAdpQnSIJfliUHUgOfm3/ML0mJSCXzY0psoI2E12nDXdDhNhFTVAcGRJO58xenxu2iHvpMH/DkbdG87SfCl/Rmz4pgJ68w1E
aN/2XHDg3VG0OMI9JsFEWA/M+RQ6ohMj9yJ/NiZug3ChW4x26/gQjLuyzVMEXJWuPPmFmmvcbc2Vg+5CNSkpcU24F8HcLmeP+WFu
i8d77K99Dl3oCsNoUmQaXbNzHEpwhkThXewmo9a+lHsHCAoswUZs6Q5ukxmrMZbMzW4IVtwmITeQ/j+O+LC4HZf3OHGf6LJoYXS4
D0IDLa/KcffMAXPi6cIIqT6nV/eH1g6kYzPde7eir8eoNbr+8QMXhKdBVRtzs/WgPbvmN4gWjlYgdYCI+MsEeJghBzxHX1V7fxOz
Bh+V1vunRbXQhOsX1dzHHMkKaiwHdzRWYKzr6BetVAkeJEyu7R1hG4aSlmFmCbZDTruY1rs/YckgqwQcYMgIMz3GK0M5vPUE2c5X
VPy/bIzrbpYGT+IbNoIv6GsOKYFL2xo253PxdOh8JX7+4uc8UhwCXcb1bMu8lLo9Fc1M0weNK2Gh+sGHgqCq4XJCOH/ImfVS+cDa
ml10fCyFc+an0GB7EwRaZTs7wW4Ic0fN9BwOq/sqCr7QBZCWRJ/kJGnzun1GbFqY9kRhqj0QmLZsFFSOLyjfQ35QAaFlVIIn5tkw
MLaqlZtrQISWsSa75pnWCpL2DvtPT3UKrYJ8e4ObLZB7W4Ho/AKAw4JDa4lykbXtaI19cm2OZMHU+fgG1x9AW0s2tKo+8Ilc76Un
FdVPYoIBcOnSZ2s8KbqdnCQ0Qx+vyaJZKctQ1OEACXlnQsky6Mazlmp8mfmBNfVfAfd9DpiL/rwv7FERPmGpT9QEuUNIpUeFIW1o
NODjIAm5GosMJk+mfFtKm3qelVl9c5mEpPchK/4bpWg2cVKj+GhXwdRkDSFOaS1PnM3Jncz4PXve+chit5uvXrtx1brD9E9S2F3c
Ysjd9GdsTezaSUcKQrXD3hb2uHovIDSVOVjiYHvPuzepnwXkYmLClG2o0EkuEjb5pcVmxLuKARYJzvkn3x07abrpTPqJLVnh/MT2
VrhdIwgnYJyZ6DvFHi0I/T+pe8Vv1WOc7cNrmfl+AXeQh3dWnq2fpAmPvB2Ypv0RQdIe3VcCK3Zri7oAbc52QqngonerSGz6+154
WAo5xw"""
>>> timestamp
=
1603805169
>>> base64_dec_data
=
base64.b64decode(lif.ljust((
len
(lif)
+
3
)
/
/
4
*
4
,
"="
))
>>> asn1_data
=
b''
>>>
for
i
in
range
(
0
,
len
(base64_dec_data)
/
/
4
):
>>> asn1_data
+
=
struct.pack(
"I"
, struct.unpack(
"I"
, base64_dec_data[i
*
4
:i
*
4
+
4
])[
0
] ^ timestamp)
>>> timestamp
=
(
0x5917
*
timestamp
+
0x4A6B
)
%
0x100000000
>>>
if
((
len
(base64_dec_data)
%
4
) !
=
0
):
>>> asn1_data
+
=
base64_dec_data[
-
(
len
(base64_dec_data)
%
4
):]
>>>
print
(asn1_data.
hex
())
>>> a08204b006092a864886f70d010702a08204a13082049d020101310d300b06096086480165030402013081db060a2b0601040182db450201a081ccff816481c7ff812137df813508636d626f7870676dff812512df4e020001df54020001df20050000000000ff7a12df4e020001df54020001df20050000000000ff6412df81320500272adc71df8133050027048f5fff7d3ade3054006500720072006100200043006f006e007400610069006e00650072002000760032002e0033002e0031002e003400df720500005b9126ff810828df81140432303031df7f050000000000ff810014ff810410c101ffc101ffc101ffc10100c2020001ff81050adf815b0100df815c0100a08203323082017b30820128a0030201020204b2d05e01300a06082a8648ce3d040302302631153013060355040a0c0c574942552d53595354454d53310d300b06035504030c04526f6f74301e170d3135303130313030303030305a170d3335313233313233353935395a303131153013060355040a0c0c574942552d53595354454d533118301606035504030c0f576962752d50726f64756374696f6e304e301006072a8648ce3d020106052b81040021033a00043237dd50e5a0a5a938e288473613123926b1c2fb115277be218845bda6e014ecf1d199058f77057880ed3cc583f9ef09b9e480d78e30f24a81150078a4685955f6773249e8576c2a5d48fbbbeac6e2821500c68c60c4c5152682205b1f4055a3f82db9a60887a316301430120603551d130101ff040830060101ff020101300a06082a8648ce3d040302034100303e021d00e15df535015975891e7f1ac8f0b17e077cc10e67452746675ae05226021d00b6e5a1abca94d5b8feabc794941007839261f779b4dff4b34b7bc774308201af3082015ea0030201020204b2d064b3300a06082a8648ce3d040302303131153013060355040a0c0c574942552d53595354454d533118301606035504030c0f576962752d50726f64756374696f6e301e170d3135303130313030303030305a170d3335313233313233353935395a30203110300e060355040a0c0736303030393334310c300a06035504030c034c504b304e301006072a8648ce3d020106052b81040021033a00045054299d03a73f13eb24353dbe91e9a68033c3015752813daa0b6b50eb5759440792e97b0a39a29a7338d2b783957b852600c4db373568c9811500c68c60c4c5152682205b1f4055a3f82db9a608878215000bebffd7689a1c9b087a605e4632dba396264292a3523050300f0603551d130101ff04053003010100300f0603551d0f0101ff04050303000f00302c060a2b0601040182db4503010101ff041bff7618df72035b9126ff780fdf815d01ffdf815e01ffdf815f01ff300a06082a8648ce3d040302033f00303c021c34ea5bebadf0701722a15bd0e1d0b07a16162bcccfe4302ff8d7142b021c0911ebf5074936aab9d76b626f7b49359e1eea60c02e5ba2dfd787af3175307302010182140bebffd7689a1c9b087a605e4632dba396264292300b0609608648016503040201300a06082a8648ce3d040302043f303d021c491d0676d5bed1e838774be564a77cdf9b50eb1e6327c53c139a8673021d00e43d0ef8fccd80fdd1573c187095d68c9ebf856da0d7ec0dd99a5443
|
从CodeMeterLin中可以收集asn1的相关定义,其中部分asn1定义存在嵌套关系。
WIBU-FILE是LIF文件的第一层asn1定义,绝大多数asn1数据都是从WIBU-FILE开始,包括RAC文件、RAU文件、DYN文件等。
WIBU-FILE包含两个结构,一种以signed开始,另一种以envelope开始,两种结构实际上均符合PKCS#7的定义。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
-
-
Wibu
-
File
.asn1
WIBU
-
FILE
DEFINITIONS ::
=
BEGIN
Wibu
-
File
::
=
CHOICE
{
signed[
0
] IMPLICIT Wibu
-
File
-
Signed,
envelope[
1
] IMPLICIT Wibu
-
File
-
Enveloped
}
Wibu
-
File
-
Signed ::
=
SEQUENCE
{
contentType ContentType,
content[
0
] EXPLICIT SignedData
}
ContentType ::
=
OBJECT
IDENTIFIER
SignedData ::
=
SEQUENCE
{
version VersionPKCS7,
digestAlgorithms DigestAlgorithmIdentifiers,
contentInfo ContentInfo,
certificates[
0
] IMPLICIT ExtendedCertificatesAndCertificates OPTIONAL,
crls[
1
] IMPLICIT CertificateRevocationLists OPTIONAL,
signerInfos SignerInfos
}
VersionPKCS7 ::
=
INTEGER
DigestAlgorithmIdentifiers ::
=
SET
OF DigestAlgorithmIdentifier
DigestAlgorithmIdentifier ::
=
SEQUENCE OF
OBJECT
IDENTIFIER
ContentInfo ::
=
SEQUENCE
{
contentType ContentType,
content[
0
] EXPLICIT
ANY
OPTIONAL
}
ExtendedCertificatesAndCertificates ::
=
SET
OF ExtendedCertificateOrCertificate
ExtendedCertificateOrCertificate ::
=
ANY
CertificateRevocationLists ::
=
SET
{
dummy INTEGER
}
SignerInfos ::
=
SET
OF SignerInfo
SignerInfo ::
=
SEQUENCE
{
version VersionPKCS7,
signerIdentifier SignerIdentifier,
digestAlgorithm DigestAlgorithmIdentifier,
authenticatedAttributes[
0
] IMPLICIT Attributes OPTIONAL,
digestEncryptionAlgorithm DigestEncryptionAlgorithmIdentifier,
encryptedDigest EncryptedDigest,
unauthenticatedAttributes[
1
] IMPLICIT Attributes OPTIONAL
}
SignerIdentifier ::
=
CHOICE
{
subjectKeyIdentifier[
2
] IMPLICIT SubjectKeyIdentifier
}
SubjectKeyIdentifier ::
=
OCTET STRING
Attributes ::
=
SET
OF Attribute7
Attribute7 ::
=
SEQUENCE
{
type
OBJECT
IDENTIFIER,
values Values,
valuesWithContext ValuesWithContext OPTIONAL
}
Values ::
=
SET
OF
ANY
ValuesWithContext ::
=
SET
OF
ANY
DigestEncryptionAlgorithmIdentifier ::
=
SEQUENCE OF
OBJECT
IDENTIFIER
EncryptedDigest ::
=
OCTET STRING
Wibu
-
File
-
Enveloped ::
=
SEQUENCE
{
contentType ContentType,
content[
0
] EXPLICIT EnvelopedData
}
EnvelopedData ::
=
SEQUENCE
{
version VersionPKCS7,
recipientInfos RecipientInfos,
encryptedContentInfo EncryptedContentInfo
}
RecipientInfos ::
=
SET
OF RecipientInfo
RecipientInfo ::
=
SEQUENCE
{
version VersionPKCS7,
signerIdentifier SignerIdentifier,
keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier,
encryptedKey EncryptedKey
}
KeyEncryptionAlgorithmIdentifier ::
=
SEQUENCE OF
OBJECT
IDENTIFIER
EncryptedKey ::
=
OCTET STRING
EncryptedContentInfo ::
=
SEQUENCE
{
contentType ContentType,
contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier,
encryptedContent[
0
] IMPLICIT EncryptedContent OPTIONAL
}
ContentEncryptionAlgorithmIdentifier ::
=
SEQUENCE OF
OBJECT
IDENTIFIER
EncryptedContent ::
=
OCTET STRING
END
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
>>>
import
asn1tools
>>>
import
datetime
>>>
def
write_line(fd, level, line):
>>>
if
(line !
=
""):
>>>
if
(fd
=
=
None
):
>>>
print
(
" "
*
level
+
line, end
=
"")
>>>
pass
>>>
else
:
>>> fd.write(
" "
*
level
+
line)
>>>
>>>
def
print_asn1_data(data, fd
=
None
, level
=
0
):
>>>
if
(
type
(data)
=
=
tuple
):
>>> key
=
data[
0
]
>>> val
=
data[
1
]
>>>
>>>
if
(
type
(key)
=
=
bytes
or
type
(key)
=
=
bytearray):
>>> print_asn1_data(key, fd, level
+
2
)
>>>
else
:
>>>
if
(
type
(val)
=
=
dict
or
(
type
(val)
=
=
tuple
and
type
(val[
0
])
=
=
str
)
or
type
(val)
=
=
list
):
>>> write_line(fd, level,
"<%s>\n"
%
key)
>>>
else
:
>>> write_line(fd, level,
"<%s> "
%
key)
>>> print_asn1_data(val, fd, level
+
2
)
>>>
if
(
type
(val)
=
=
dict
or
(
type
(val)
=
=
tuple
and
type
(val[
0
])
=
=
str
)
or
type
(val)
=
=
list
):
>>> write_line(fd, level,
"</%s>\n"
%
key)
>>>
else
:
>>> write_line(fd,
0
,
" </%s>\n"
%
key)
>>>
elif
(
type
(data)
=
=
dict
):
>>>
for
key, val
in
data.items():
>>>
if
(
type
(val)
=
=
dict
or
(
type
(val)
=
=
tuple
and
type
(val[
0
])
=
=
str
)
or
type
(val)
=
=
list
):
>>> write_line(fd, level,
"<%s>\n"
%
key)
>>>
else
:
>>> write_line(fd, level,
"<%s> "
%
key)
>>> print_asn1_data(val, fd, level
+
2
)
>>>
if
(
type
(val)
=
=
dict
or
(
type
(val)
=
=
tuple
and
type
(val[
0
])
=
=
str
)
or
type
(val)
=
=
list
):
>>> write_line(fd, level,
"</%s>\n"
%
key)
>>>
else
:
>>> write_line(fd,
0
,
" </%s>\n"
%
key)
>>>
elif
(
type
(data)
=
=
list
):
>>> cnt
=
0
>>>
for
val
in
data:
>>>
if
(
type
(val)
=
=
dict
or
(
type
(val)
=
=
tuple
and
type
(val[
0
])
=
=
str
)
or
type
(val)
=
=
list
):
>>> write_line(fd, level,
"<%d>\n"
%
cnt)
>>>
else
:
>>> write_line(fd, level,
"<%d> "
%
cnt)
>>> print_asn1_data(val, fd, level
+
2
)
>>>
if
(
type
(val)
=
=
dict
or
(
type
(val)
=
=
tuple
and
type
(val[
0
])
=
=
str
)
or
type
(val)
=
=
list
):
>>> write_line(fd, level,
"</%d>\n"
%
cnt)
>>>
else
:
>>> write_line(fd,
0
,
" </%d>\n"
%
cnt)
>>> cnt
+
=
1
>>>
elif
(
type
(data)
=
=
str
):
>>> write_line(fd,
0
,
"%s"
%
data)
>>>
elif
(
type
(data)
=
=
int
):
>>> write_line(fd,
0
,
"%d"
%
data)
>>>
elif
(
type
(data)
=
=
bytearray
or
type
(data)
=
=
bytes):
>>> output
=
""
>>>
for
b
in
data:
>>> output
+
=
"%02X "
%
b
>>> output
=
output.strip()
>>> write_line(fd,
0
, output)
>>>
elif
(
type
(data)
=
=
bool
):
>>> write_line(fd,
0
,
"%s"
%
data)
>>>
elif
(
type
(data)
=
=
datetime.datetime):
>>> write_line(fd,
0
,
"%s"
%
data)
>>>
elif
(data
=
=
None
):
>>> write_line(fd,
0
,
"NULL"
)
>>>
else
:
>>>
raise
(Exception(
"type: %s"
%
type
(data)))
>>> asn1_data
=
bytes.fromhex(
"a08204b006092a864886f70d010702a08204a13082049d020101310d300b06096086480165030402013081db060a2b0601040182db450201a081ccff816481c7ff812137df813508636d626f7870676dff812512df4e020001df54020001df20050000000000ff7a12df4e020001df54020001df20050000000000ff6412df81320500272adc71df8133050027048f5fff7d3ade3054006500720072006100200043006f006e007400610069006e00650072002000760032002e0033002e0031002e003400df720500005b9126ff810828df81140432303031df7f050000000000ff810014ff810410c101ffc101ffc101ffc10100c2020001ff81050adf815b0100df815c0100a08203323082017b30820128a0030201020204b2d05e01300a06082a8648ce3d040302302631153013060355040a0c0c574942552d53595354454d53310d300b06035504030c04526f6f74301e170d3135303130313030303030305a170d3335313233313233353935395a303131153013060355040a0c0c574942552d53595354454d533118301606035504030c0f576962752d50726f64756374696f6e304e301006072a8648ce3d020106052b81040021033a00043237dd50e5a0a5a938e288473613123926b1c2fb115277be218845bda6e014ecf1d199058f77057880ed3cc583f9ef09b9e480d78e30f24a81150078a4685955f6773249e8576c2a5d48fbbbeac6e2821500c68c60c4c5152682205b1f4055a3f82db9a60887a316301430120603551d130101ff040830060101ff020101300a06082a8648ce3d040302034100303e021d00e15df535015975891e7f1ac8f0b17e077cc10e67452746675ae05226021d00b6e5a1abca94d5b8feabc794941007839261f779b4dff4b34b7bc774308201af3082015ea0030201020204b2d064b3300a06082a8648ce3d040302303131153013060355040a0c0c574942552d53595354454d533118301606035504030c0f576962752d50726f64756374696f6e301e170d3135303130313030303030305a170d3335313233313233353935395a30203110300e060355040a0c0736303030393334310c300a06035504030c034c504b304e301006072a8648ce3d020106052b81040021033a00045054299d03a73f13eb24353dbe91e9a68033c3015752813daa0b6b50eb5759440792e97b0a39a29a7338d2b783957b852600c4db373568c9811500c68c60c4c5152682205b1f4055a3f82db9a608878215000bebffd7689a1c9b087a605e4632dba396264292a3523050300f0603551d130101ff04053003010100300f0603551d0f0101ff04050303000f00302c060a2b0601040182db4503010101ff041bff7618df72035b9126ff780fdf815d01ffdf815e01ffdf815f01ff300a06082a8648ce3d040302033f00303c021c34ea5bebadf0701722a15bd0e1d0b07a16162bcccfe4302ff8d7142b021c0911ebf5074936aab9d76b626f7b49359e1eea60c02e5ba2dfd787af3175307302010182140bebffd7689a1c9b087a605e4632dba396264292300b0609608648016503040201300a06082a8648ce3d040302043f303d021c491d0676d5bed1e838774be564a77cdf9b50eb1e6327c53c139a8673021d00e43d0ef8fccd80fdd1573c187095d68c9ebf856da0d7ec0dd99a5443"
)
>>> asn1_def
=
asn1tools.compile_files([
"asn1/Wibu-File.asn1"
,
"asn1/LIF-Content.asn1"
,
"asn1/Certificate.asn1"
,
"asn1/SignerSignature.asn1"
],
"der"
)
>>>
>>> asn_wibu_f_res
=
asn1_def.decode(
"Wibu-File"
, asn1_data)
>>> print_asn1_data(asn_wibu_f_res)
<signed>
<contentType>
1.2
.
840.113549
.
1.7
.
2
<
/
contentType>
<content>
<version>
1
<
/
version>
<digestAlgorithms>
<
0
>
<
0
>
2.16
.
840.1
.
101.3
.
4.2
.
1
<
/
0
>
<
/
0
>
<
/
digestAlgorithms>
<contentInfo>
<contentType>
1.3
.
6.1
.
4.1
.
44485.2
.
1
<
/
contentType>
<content> FF
81
64
81
C7 FF
81
21
37
DF
81
35
08
63
6D
62
6F
78
70
67
6D
FF
81
25
12
DF
4E
02
00
01
DF
54
02
00
01
DF
20
05
00
00
00
00
00
FF
7A
12
DF
4E
02
00
01
DF
54
02
00
01
DF
20
05
00
00
00
00
00
FF
64
12
DF
81
32
05
00
27
2A
DC
71
DF
81
33
05
00
27
04
8F
5F
FF
7D
3A
DE
30
54
00
65
00
72
00
72
00
61
00
20
00
43
00
6F
00
6E
00
74
00
61
00
69
00
6E
00
65
00
72
00
20
00
76
00
32
00
2E
00
33
00
2E
00
31
00
2E
00
34
00
DF
72
05
00
00
5B
91
26
FF
81
08
28
DF
81
14
04
32
30
30
31
DF
7F
05
00
00
00
00
00
FF
81
00
14
FF
81
04
10
C1
01
FF C1
01
FF C1
01
FF C1
01
00
C2
02
00
01
FF
81
05
0A
DF
81
5B
01
00
DF
81
5C
01
00
<
/
content>
<
/
contentInfo>
<certificates>
<
0
>
30
82
01
7B
30
82
01
28
A0
03
02
01
02
02
04
B2 D0
5E
01
30
0A
06
08
2A
86
48
CE
3D
04
03
02
30
26
31
15
30
13
06
03
55
04
0A
0C
0C
57
49
42
55
2D
53
59
53
54
45
4D
53
31
0D
30
0B
06
03
55
04
03
0C
04
52
6F
6F
74
30
1E
17
0D
31
35
30
31
30
31
30
30
30
30
30
30
5A
17
0D
33
35
31
32
33
31
32
33
35
39
35
39
5A
30
31
31
15
30
13
06
03
55
04
0A
0C
0C
57
49
42
55
2D
53
59
53
54
45
4D
53
31
18
30
16
06
03
55
04
03
0C
0F
57
69
62
75
2D
50
72
6F
64
75
63
74
69
6F
6E
30
4E
30
10
06
07
2A
86
48
CE
3D
02
01
06
05
2B
81
04
00
21
03
3A
00
04
32
37
DD
50
E5 A0 A5 A9
38
E2
88
47
36
13
12
39
26
B1 C2 FB
11
52
77
BE
21
88
45
BD A6 E0
14
EC F1 D1
99
05
8F
77
05
78
80
ED
3C
C5
83
F9 EF
09
B9 E4
80
D7
8E
30
F2
4A
81
15
00
78
A4
68
59
55
F6
77
32
49
E8
57
6C
2A
5D
48
FB BB EA C6 E2
82
15
00
C6
8C
60
C4 C5
15
26
82
20
5B
1F
40
55
A3 F8
2D
B9 A6
08
87
A3
16
30
14
30
12
06
03
55
1D
13
01
01
FF
04
08
30
06
01
01
FF
02
01
01
30
0A
06
08
2A
86
48
CE
3D
04
03
02
03
41
00
30
3E
02
1D
00
E1
5D
F5
35
01
59
75
89
1E
7F
1A
C8 F0 B1
7E
07
7C
C1
0E
67
45
27
46
67
5A
E0
52
26
02
1D
00
B6 E5 A1 AB CA
94
D5 B8 FE AB C7
94
94
10
07
83
92
61
F7
79
B4 DF F4 B3
4B
7B
C7
74
<
/
0
>
<
1
>
30
82
01
AF
30
82
01
5E
A0
03
02
01
02
02
04
B2 D0
64
B3
30
0A
06
08
2A
86
48
CE
3D
04
03
02
30
31
31
15
30
13
06
03
55
04
0A
0C
0C
57
49
42
55
2D
53
59
53
54
45
4D
53
31
18
30
16
06
03
55
04
03
0C
0F
57
69
62
75
2D
50
72
6F
64
75
63
74
69
6F
6E
30
1E
17
0D
31
35
30
31
30
31
30
30
30
30
30
30
5A
17
0D
33
35
31
32
33
31
32
33
35
39
35
39
5A
30
20
31
10
30
0E
06
03
55
04
0A
0C
07
36
30
30
30
39
33
34
31
0C
30
0A
06
03
55
04
03
0C
03
4C
50
4B
30
4E
30
10
06
07
2A
86
48
CE
3D
02
01
06
05
2B
81
04
00
21
03
3A
00
04
50
54
29
9D
03
A7
3F
13
EB
24
35
3D
BE
91
E9 A6
80
33
C3
01
57
52
81
3D
AA
0B
6B
50
EB
57
59
44
07
92
E9
7B
0A
39
A2
9A
73
38
D2 B7
83
95
7B
85
26
00
C4 DB
37
35
68
C9
81
15
00
C6
8C
60
C4 C5
15
26
82
20
5B
1F
40
55
A3 F8
2D
B9 A6
08
87
82
15
00
0B
EB FF D7
68
9A
1C
9B
08
7A
60
5E
46
32
DB A3
96
26
42
92
A3
52
30
50
30
0F
06
03
55
1D
13
01
01
FF
04
05
30
03
01
01
00
30
0F
06
03
55
1D
0F
01
01
FF
04
05
03
03
00
0F
00
30
2C
06
0A
2B
06
01
04
01
82
DB
45
03
01
01
01
FF
04
1B
FF
76
18
DF
72
03
5B
91
26
FF
78
0F
DF
81
5D
01
FF DF
81
5E
01
FF DF
81
5F
01
FF
30
0A
06
08
2A
86
48
CE
3D
04
03
02
03
3F
00
30
3C
02
1C
34
EA
5B
EB AD F0
70
17
22
A1
5B
D0 E1 D0 B0
7A
16
16
2B
CC CF E4
30
2F
F8 D7
14
2B
02
1C
09
11
EB F5
07
49
36
AA B9 D7
6B
62
6F
7B
49
35
9E
1E
EA
60
C0
2E
5B
A2 DF D7
87
AF <
/
1
>
<
/
certificates>
<signerInfos>
<
0
>
<version>
1
<
/
version>
<signerIdentifier>
<subjectKeyIdentifier>
0B
EB FF D7
68
9A
1C
9B
08
7A
60
5E
46
32
DB A3
96
26
42
92
<
/
subjectKeyIdentifier>
<
/
signerIdentifier>
<digestAlgorithm>
<
0
>
2.16
.
840.1
.
101.3
.
4.2
.
1
<
/
0
>
<
/
digestAlgorithm>
<digestEncryptionAlgorithm>
<
0
>
1.2
.
840.10045
.
4.3
.
2
<
/
0
>
<
/
digestEncryptionAlgorithm>
<encryptedDigest>
30
3D
02
1C
49
1D
06
76
D5 BE D1 E8
38
77
4B
E5
64
A7
7C
DF
9B
50
EB
1E
63
27
C5
3C
13
9A
86
73
02
1D
00
E4
3D
0E
F8 FC CD
80
FD D1
57
3C
18
70
95
D6
8C
9E
BF
85
6D
A0 D7 EC
0D
D9
9A
54
43
<
/
encryptedDigest>
<
/
0
>
<
/
signerInfos>
<
/
content>
<
/
signed>
|
signed结构中的content虽然是ANY类型,但可以通过contentType来判断content的类型。而oid1.3.6.1.4.1.44485.2.1正是指content需要使用LIF-Content进行编解码。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
-
-
LIF
-
Content.asn1
LIF
-
CONTENT DEFINITIONS ::
=
BEGIN
LIF
-
Content ::
=
[PRIVATE
228
] IMPLICIT SEQUENCE
{
sw
-
specs[PRIVATE
161
] IMPLICIT Software
-
Specs,
clocks[PRIVATE
100
] IMPLICIT Clocks,
license
-
description[PRIVATE
125
] IMPLICIT License
-
Description,
binding[PRIVATE
136
] IMPLICIT Binding
-
Scheme,
cmact
-
options[PRIVATE
133
] IMPLICIT CmAct
-
Options,
mask[PRIVATE
142
] IMPLICIT Mask OPTIONAL
}
Software
-
Specs ::
=
[PRIVATE
161
] IMPLICIT SEQUENCE
{
creator
-
name[PRIVATE
181
] IMPLICIT UTF8String,
creator
-
version[PRIVATE
165
] IMPLICIT
Format
-
Version,
required
-
version[PRIVATE
122
] IMPLICIT
Format
-
Version
}
Format
-
Version ::
=
[PRIVATE
122
] IMPLICIT SEQUENCE
{
sfl[PRIVATE
78
] IMPLICIT UInt8,
sfh[PRIVATE
84
] IMPLICIT UInt8,
feature
-
flags[PRIVATE
32
] IMPLICIT UInt32
}
UInt8 ::
=
[PRIVATE
31
] IMPLICIT INTEGER
UInt32 ::
=
[PRIVATE
34
] IMPLICIT INTEGER
Clocks ::
=
[PRIVATE
100
] IMPLICIT SEQUENCE
{
box
-
time[PRIVATE
178
] IMPLICIT Seconds
-
Since
-
2000
,
certified
-
time[PRIVATE
179
] IMPLICIT Seconds
-
Since
-
2000
}
Seconds
-
Since
-
2000
::
=
[PRIVATE
180
] IMPLICIT INTEGER
License
-
Description ::
=
[PRIVATE
125
] IMPLICIT SEQUENCE
{
license
-
description[PRIVATE
30
] IMPLICIT OCTET STRING,
-
-
BMPString, it does't work well
in
asn1tools, beacase asn1tools only support utf
-
8
, but here
is
utf
-
16
firm
-
code[PRIVATE
114
] IMPLICIT Firm
-
Code
}
Firm
-
Code ::
=
[PRIVATE
114
] IMPLICIT INTEGER
Binding
-
Scheme ::
=
[PRIVATE
136
] IMPLICIT SEQUENCE
{
cmact
-
id
[PRIVATE
148
] IMPLICIT CmAct
-
ID
,
telephone
-
id
[PRIVATE
127
] IMPLICIT Telephone
-
ID
,
binding
-
method[PRIVATE
128
] EXPLICIT Binding
-
Method
}
CmAct
-
ID
::
=
[PRIVATE
148
] IMPLICIT IA5String
Telephone
-
ID
::
=
[PRIVATE
127
] IMPLICIT INTEGER
Binding
-
Method ::
=
CHOICE
{
smartbind[PRIVATE
129
] IMPLICIT SmartBind
-
Parameters,
custom
-
binding[PRIVATE
131
] IMPLICIT CustomBinding
-
Parameters,
dcbn
-
classic[PRIVATE
132
] IMPLICIT DCBN
-
Parameters,
nonebind[PRIVATE
231
] IMPLICIT NULL,
cm
-
server
-
ip[PRIVATE
232
] IMPLICIT NULL,
serial
-
number[PRIVATE
233
] IMPLICIT NULL,
random[PRIVATE
234
] IMPLICIT NULL
}
SmartBind
-
Parameters ::
=
[PRIVATE
129
] IMPLICIT SEQUENCE
{
heuristic[PRIVATE
31
] IMPLICIT UInt8,
redundancy
-
level[PRIVATE
130
] IMPLICIT Redundancy
-
Level
}
Redundancy
-
Level ::
=
[PRIVATE
130
] IMPLICIT INTEGER
CustomBinding
-
Parameters ::
=
[PRIVATE
131
] IMPLICIT IA5String
DCBN
-
Parameters ::
=
[PRIVATE
132
] IMPLICIT SEQUENCE
{
disk[PRIVATE
1
] IMPLICIT BOOLEAN,
cpu
-
type
[PRIVATE
1
] IMPLICIT BOOLEAN,
board[PRIVATE
1
] IMPLICIT BOOLEAN,
network[PRIVATE
1
] IMPLICIT BOOLEAN,
tolerance[PRIVATE
2
] IMPLICIT UInt8 OPTIONAL
}
CmAct
-
Options ::
=
[PRIVATE
133
] IMPLICIT SEQUENCE
{
allow
-
vm[PRIVATE
219
] IMPLICIT BOOLEAN,
allow
-
reimport[PRIVATE
220
] IMPLICIT BOOLEAN
}
Mask ::
=
[PRIVATE
142
] IMPLICIT INTEGER
END
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
>>> lif
=
bytes.fromhex(
"FF816481C7FF812137DF813508636D626F7870676DFF812512DF4E020001DF54020001DF20050000000000FF7A12DF4E020001DF54020001DF20050000000000FF6412DF81320500272ADC71DF8133050027048F5FFF7D3ADE3054006500720072006100200043006F006E007400610069006E00650072002000760032002E0033002E0031002E003400DF720500005B9126FF810828DF81140432303031DF7F050000000000FF810014FF810410C101FFC101FFC101FFC10100C2020001FF81050ADF815B0100DF815C0100"
)
>>> asn_lif_res
=
asn1_def.decode(
"LIF-Content"
, lif)
>>> print_asn1_data(asn_lif_res)
<sw
-
specs>
<creator
-
name> cmboxpgm <
/
creator
-
name>
<creator
-
version>
<sfl>
1
<
/
sfl>
<sfh>
1
<
/
sfh>
<feature
-
flags>
0
<
/
feature
-
flags>
<
/
creator
-
version>
<required
-
version>
<sfl>
1
<
/
sfl>
<sfh>
1
<
/
sfh>
<feature
-
flags>
0
<
/
feature
-
flags>
<
/
required
-
version>
<
/
sw
-
specs>
<clocks>
<box
-
time>
657120369
<
/
box
-
time>
<certified
-
time>
654610271
<
/
certified
-
time>
<
/
clocks>
<license
-
description>
<license
-
description>
54
00
65
00
72
00
72
00
61
00
20
00
43
00
6F
00
6E
00
74
00
61
00
69
00
6E
00
65
00
72
00
20
00
76
00
32
00
2E
00
33
00
2E
00
31
00
2E
00
34
00
<
/
license
-
description>
<firm
-
code>
6000934
<
/
firm
-
code>
<
/
license
-
description>
<binding>
<cmact
-
id
>
2001
<
/
cmact
-
id
>
<telephone
-
id
>
0
<
/
telephone
-
id
>
<binding
-
method>
<dcbn
-
classic>
<disk>
True
<
/
disk>
<cpu
-
type
>
True
<
/
cpu
-
type
>
<board>
True
<
/
board>
<network>
False
<
/
network>
<tolerance>
1
<
/
tolerance>
<
/
dcbn
-
classic>
<
/
binding
-
method>
<
/
binding>
<cmact
-
options>
<allow
-
vm>
False
<
/
allow
-
vm>
<allow
-
reimport>
False
<
/
allow
-
reimport>
<
/
cmact
-
options>
|
LIF文件中的数字证书用于签名。多个证书还构成了证书链,证书链中的每个父节点都可以校验子节点下的任何一份证书。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
|
-
-
Certificate.asn1
CERTIFICATE DEFINITIONS ::
=
BEGIN
Certificate ::
=
SEQUENCE
{
tbsCertificate TBSCertificate,
signatureAlgorithm AlgorithmIdentifier,
signature BIT STRING
}
TBSCertificate ::
=
SEQUENCE
{
version[
0
] EXPLICIT Version OPTIONAL,
serialNumber CertificateSerialNumber,
signature AlgorithmIdentifier,
issuer Name,
validity Validity,
subject Name,
subjectPublicKeyInfo SubjectPublicKeyInfo,
issuerUniqueID[
1
] IMPLICIT UniqueIdentifier OPTIONAL,
subjectUniqueID[
2
] IMPLICIT UniqueIdentifier OPTIONAL,
extensions[
3
] EXPLICIT Extensions OPTIONAL
}
Version ::
=
INTEGER
CertificateSerialNumber ::
=
INTEGER
AlgorithmIdentifier ::
=
SEQUENCE
{
algorithm
OBJECT
IDENTIFIER,
parameters
ANY
OPTIONAL
}
Name ::
=
CHOICE
{
rdnSequence RDNSequence
}
RDNSequence ::
=
SEQUENCE OF RelativeDistinguishedName
RelativeDistinguishedName ::
=
SET
OF AttributeTypeAndValue
AttributeTypeAndValue ::
=
SEQUENCE
{
type
AttributeType,
value AttributeValue
}
AttributeType ::
=
OBJECT
IDENTIFIER
AttributeValue ::
=
UTF8String
Validity ::
=
SEQUENCE
{
notBefore Time,
notAfter Time
}
Time ::
=
CHOICE
{
utcTime UTCTime,
generalTime GeneralizedTime
}
SubjectPublicKeyInfo ::
=
SEQUENCE
{
algorithm AlgorithmIdentifier,
subjectPublicKey BIT STRING
}
UniqueIdentifier ::
=
BIT STRING
Extensions ::
=
SEQUENCE OF Extension
Extension ::
=
SEQUENCE
{
extnID
OBJECT
IDENTIFIER,
critical BOOLEAN OPTIONAL,
extnValue OCTET STRING
}
END
|
1
2
3
4
5
6
7
8
9
|
-
-
SignerSignature.asn1
SIGNERSIGNATURE DEFINITIONS ::
=
BEGIN
SignerSignature ::
=
SEQUENCE
{
r INTEGER,
s INTEGER
}
END
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
|
>>> cert1
=
bytes.fromhex(
"3082017B30820128A0030201020204B2D05E01300A06082A8648CE3D040302302631153013060355040A0C0C574942552D53595354454D53310D300B06035504030C04526F6F74301E170D3135303130313030303030305A170D3335313233313233353935395A303131153013060355040A0C0C574942552D53595354454D533118301606035504030C0F576962752D50726F64756374696F6E304E301006072A8648CE3D020106052B81040021033A00043237DD50E5A0A5A938E288473613123926B1C2FB115277BE218845BDA6E014ECF1D199058F77057880ED3CC583F9EF09B9E480D78E30F24A81150078A4685955F6773249E8576C2A5D48FBBBEAC6E2821500C68C60C4C5152682205B1F4055A3F82DB9A60887A316301430120603551D130101FF040830060101FF020101300A06082A8648CE3D040302034100303E021D00E15DF535015975891E7F1AC8F0B17E077CC10E67452746675AE05226021D00B6E5A1ABCA94D5B8FEABC794941007839261F779B4DFF4B34B7BC774"
)
>>> cert2
=
bytes.fromhex(
"308201AF3082015EA0030201020204B2D064B3300A06082A8648CE3D040302303131153013060355040A0C0C574942552D53595354454D533118301606035504030C0F576962752D50726F64756374696F6E301E170D3135303130313030303030305A170D3335313233313233353935395A30203110300E060355040A0C0736303030393334310C300A06035504030C034C504B304E301006072A8648CE3D020106052B81040021033A00045054299D03A73F13EB24353DBE91E9A68033C3015752813DAA0B6B50EB5759440792E97B0A39A29A7338D2B783957B852600C4DB373568C9811500C68C60C4C5152682205B1F4055A3F82DB9A608878215000BEBFFD7689A1C9B087A605E4632DBA396264292A3523050300F0603551D130101FF04053003010100300F0603551D0F0101FF04050303000F00302C060A2B0601040182DB4503010101FF041BFF7618DF72035B9126FF780FDF815D01FFDF815E01FFDF815F01FF300A06082A8648CE3D040302033F00303C021C34EA5BEBADF0701722A15BD0E1D0B07A16162BCCCFE4302FF8D7142B021C0911EBF5074936AAB9D76B626F7B49359E1EEA60C02E5BA2DFD787AF"
)
>>> asn_cert1_res
=
asn1_def.decode(
"Certificate"
, cert1)
>>> asn_cert2_res
=
asn1_def.decode(
"Certificate"
, cert2)
>>> print_asn1_data(asn_cert1_res)
<tbsCertificate>
<version>
2
<
/
version>
<serialNumber>
-
1294967295
<
/
serialNumber>
<signature>
<algorithm>
1.2
.
840.10045
.
4.3
.
2
<
/
algorithm>
<
/
signature>
<issuer>
<rdnSequence>
<
0
>
<
0
>
<
type
>
2.5
.
4.10
<
/
type
>
<value> WIBU
-
SYSTEMS <
/
value>
<
/
0
>
<
/
0
>
<
1
>
<
0
>
<
type
>
2.5
.
4.3
<
/
type
>
<value> Root <
/
value>
<
/
0
>
<
/
1
>
<
/
rdnSequence>
<
/
issuer>
<validity>
<notBefore>
<utcTime>
2015
-
01
-
01
00
:
00
:
00
<
/
utcTime>
<
/
notBefore>
<notAfter>
<utcTime>
2035
-
12
-
31
23
:
59
:
59
<
/
utcTime>
<
/
notAfter>
<
/
validity>
<subject>
<rdnSequence>
<
0
>
<
0
>
<
type
>
2.5
.
4.10
<
/
type
>
<value> WIBU
-
SYSTEMS <
/
value>
<
/
0
>
<
/
0
>
<
1
>
<
0
>
<
type
>
2.5
.
4.3
<
/
type
>
<value> Wibu
-
Production <
/
value>
<
/
0
>
<
/
1
>
<
/
rdnSequence>
<
/
subject>
<subjectPublicKeyInfo>
<algorithm>
<algorithm>
1.2
.
840.10045
.
2.1
<
/
algorithm>
<parameters>
06
05
2B
81
04
00
21
<
/
parameters>
<
/
algorithm>
<subjectPublicKey>
04
32
37
DD
50
E5 A0 A5 A9
38
E2
88
47
36
13
12
39
26
B1 C2 FB
11
52
77
BE
21
88
45
BD A6 E0
14
EC F1 D1
99
05
8F
77
05
78
80
ED
3C
C5
83
F9 EF
09
B9 E4
80
D7
8E
30
F2
4A
<
/
subjectPublicKey>
<
/
subjectPublicKeyInfo>
<issuerUniqueID>
78
A4
68
59
55
F6
77
32
49
E8
57
6C
2A
5D
48
FB BB EA C6 E2 <
/
issuerUniqueID>
<subjectUniqueID> C6
8C
60
C4 C5
15
26
82
20
5B
1F
40
55
A3 F8
2D
B9 A6
08
87
<
/
subjectUniqueID>
<extensions>
<
0
>
<extnID>
2.5
.
29.19
<
/
extnID>
<critical>
True
<
/
critical>
<extnValue>
30
06
01
01
FF
02
01
01
<
/
extnValue>
<
/
0
>
<
/
extensions>
<
/
tbsCertificate>
<signatureAlgorithm>
<algorithm>
1.2
.
840.10045
.
4.3
.
2
<
/
algorithm>
<
/
signatureAlgorithm>
<signature>
30
3E
02
1D
00
E1
5D
F5
35
01
59
75
89
1E
7F
1A
C8 F0 B1
7E
07
7C
C1
0E
67
45
27
46
67
5A
E0
52
26
02
1D
00
B6 E5 A1 AB CA
94
D5 B8 FE AB C7
94
94
10
07
83
92
61
F7
79
B4 DF F4 B3
4B
7B
C7
74
<
/
signature>
>>> print_asn1_data(asn_cert2_res)
<tbsCertificate>
<version>
2
<
/
version>
<serialNumber>
-
1294965581
<
/
serialNumber>
<signature>
<algorithm>
1.2
.
840.10045
.
4.3
.
2
<
/
algorithm>
<
/
signature>
<issuer>
<rdnSequence>
<
0
>
<
0
>
<
type
>
2.5
.
4.10
<
/
type
>
<value> WIBU
-
SYSTEMS <
/
value>
<
/
0
>
<
/
0
>
<
1
>
<
0
>
<
type
>
2.5
.
4.3
<
/
type
>
<value> Wibu
-
Production <
/
value>
<
/
0
>
<
/
1
>
<
/
rdnSequence>
<
/
issuer>
<validity>
<notBefore>
<utcTime>
2015
-
01
-
01
00
:
00
:
00
<
/
utcTime>
<
/
notBefore>
<notAfter>
<utcTime>
2035
-
12
-
31
23
:
59
:
59
<
/
utcTime>
<
/
notAfter>
<
/
validity>
<subject>
<rdnSequence>
<
0
>
<
0
>
<
type
>
2.5
.
4.10
<
/
type
>
<value>
6000934
<
/
value>
<
/
0
>
<
/
0
>
<
1
>
<
0
>
<
type
>
2.5
.
4.3
<
/
type
>
<value> LPK <
/
value>
<
/
0
>
<
/
1
>
<
/
rdnSequence>
<
/
subject>
<subjectPublicKeyInfo>
<algorithm>
<algorithm>
1.2
.
840.10045
.
2.1
<
/
algorithm>
<parameters>
06
05
2B
81
04
00
21
<
/
parameters>
<
/
algorithm>
<subjectPublicKey>
04
50
54
29
9D
03
A7
3F
13
EB
24
35
3D
BE
91
E9 A6
80
33
C3
01
57
52
81
3D
AA
0B
6B
50
EB
57
59
44
07
92
E9
7B
0A
39
A2
9A
73
38
D2 B7
83
95
7B
85
26
00
C4 DB
37
35
68
C9 <
/
subjectPublicKey>
<
/
subjectPublicKeyInfo>
<issuerUniqueID> C6
8C
60
C4 C5
15
26
82
20
5B
1F
40
55
A3 F8
2D
B9 A6
08
87
<
/
issuerUniqueID>
<subjectUniqueID>
0B
EB FF D7
68
9A
1C
9B
08
7A
60
5E
46
32
DB A3
96
26
42
92
<
/
subjectUniqueID>
<extensions>
<
0
>
<extnID>
2.5
.
29.19
<
/
extnID>
<critical>
True
<
/
critical>
<extnValue>
30
03
01
01
00
<
/
extnValue>
<
/
0
>
<
1
>
<extnID>
2.5
.
29.15
<
/
extnID>
<critical>
True
<
/
critical>
<extnValue>
03
03
00
0F
00
<
/
extnValue>
<
/
1
>
<
2
>
<extnID>
1.3
.
6.1
.
4.1
.
44485.3
.
1
<
/
extnID>
<critical>
True
<
/
critical>
<extnValue> FF
76
18
DF
72
03
5B
91
26
FF
78
0F
DF
81
5D
01
FF DF
81
5E
01
FF DF
81
5F
01
FF <
/
extnValue>
<
/
2
>
<
/
extensions>
<
/
tbsCertificate>
<signatureAlgorithm>
<algorithm>
1.2
.
840.10045
.
4.3
.
2
<
/
algorithm>
<
/
signatureAlgorithm>
<signature>
30
3C
02
1C
34
EA
5B
EB AD F0
70
17
22
A1
5B
D0 E1 D0 B0
7A
16
16
2B
CC CF E4
30
2F
F8 D7
14
2B
02
1C
09
11
EB F5
07
49
36
AA B9 D7
6B
62
6F
7B
49
35
9E
1E
EA
60
C0
2E
5B
A2 DF D7
87
AF <
/
signature>
|
使用cert2对content进行验签,其中公钥由证书中的subjectPublicKey提供,rs值由LIF文件的encryptedDigest提供,h由LIF文件的content的哈希提供,椭圆算法参数由为1.3.132.0.33,可进行椭圆算法参数查询。
1
2
3
4
5
6
7
8
|
>>>
import
hashlib
>>>
import
sha256ecdsa
>>> Q
=
{
"x"
:
0x5054299D03A73F13EB24353DBE91E9A68033C3015752813DAA0B6B50
,
"y"
:
0xEB5759440792E97B0A39A29A7338D2B783957B852600C4DB373568C9
}
>>> r
=
0x491D0676D5BED1E838774BE564A77CDF9B50EB1E6327C53C139A8673
>>> s
=
0xE43D0EF8FCCD80FDD1573C187095D68C9EBF856DA0D7EC0DD99A5443
>>> h
=
int
.from_bytes(hashlib.sha256(lif).digest(),
"big"
) >>
32
#ignore low 32bits
>>>
print
(sha256ecdsa.sha256ecdsa(h, r, s, Q, r))
True
|
从上述的分析结果看,LIF文件主要包含了授权信息和运行环境的限制,这些限制包括了操作系统、CPU等硬件、虚拟化、激活的方式等。
本文仅以LIF文件为例,RAC文件和RAU文件等均可以按照类似的过程进行解析。
由于LIF文件是带签名的,不能直接修改其中的任何内容,否则将导致验签失败。
如果想要修改LIF中的内容,就需要修改整条证书链上的所有证书,包括根证书。幸运的是,根证书同样存在于CodeMeterLin中,并且是以常量的形式的存在。所以,理论上讲,我们有机会完全控制软授权中的任何过程。
更多【wibu软授权(二)】相关视频教程:www.yxfzedu.com