首页
论坛
课程
招聘
[原创]wibu证书 - asn1码流
2022-9-8 00:54 6464

[原创]wibu证书 - asn1码流

2022-9-8 00:54
6464

前言

通过上一节的处理,我们拿到了asn1码流,这节我们将使用CodeMeterLin中asn1的定义进行更加有效的解析。

 

在wibu软授权系统中,大部分相关的数据都是使用asn1编码的,所以

asn1码流十分重要!

asn1码流十分重要!

asn1码流十分重要!

环境

  • python3.7
  • asn1tools

知识储备

ASN.1

ASN全称为Abstract Syntax Notation dotone,是定义抽象数据类型形式的标准,描绘了与任何表示数据的编码技术无关的通用数据结构,目前只定义一个版本(ASN.1)。ASN.1有​​四种类型:

  • 简单类型,是"原子的"并且没有任何组件;
  • 具有组件的结构化类型;
  • 标记类型,从其他类型派生;
  • 其他类型,包括CHOICE类型和ANY类型。

除CHOICE和ANY外,每种ASN.1类型都有一个标签,该标签由一个类型号(class)和一个非负标签号(tag)组成。当且仅当它们的标签号相同时,ASN.1类型才抽象地相同。换句话说,ASN.1类型的名称不会影响其抽象含义,只有标签会影响它的抽象含义。
上述是asn1的描述,其中最关键的是每种asn1类型都有一个标签值这句话,这意味者我们通过标签值反过来找到asn1的定义。

TLV结构

ber编码是asn1中最基础一种的编码方式,它传输格式是TLV(Tag-Length-Value)三元组。

  • Tag,指定结构的类型和嵌套关系。
  • Length,长度字段,指示结构的体长
  • Value,该字段用来存放具体的数据或嵌套的TLV结构。

Tag

bits结构如下图所示:

2 bit 1 bit 5 bit
class p/s tagv
 

class用于表示tagv所在的类属,分为以下四类

  • Universal,asn1中最基础的类型都属于这个类属,如BOOLEANINTEGER,除该类属外,其他类属都是复合类型。
  • Application,特定于应用程序的类型都属于这个类属,目前已不推荐使用。
  • Private,特定于特定企业的类型都属于这个类属,本次分析的码流使用了该类属下的多个类型。
  • Context-specific,特定于特定结构化的类型都属于这个类属,用于标记特定的上下文,不同的上下文可能具有相同的tagv但其含义不同,在本次分析的码流也会出现这种情况。

p/s用于表示TLV中的V是否为嵌套的TVL结构,当p/s为1时,表示存在嵌套。
tagv为具体的标签值,有效值为0-30,当tagv=31时,表示标签值使用长码表示,后面跟着的八元组为具体的标签值,直到八元组的最高bit不为0为止,此时八元组的最高位用于指示长码是否结束。
06

Length

length表示TLV中的V的长度,不包含T和L的长度。
当length=0x80时,表示V为不定长数据,V最后要以两个00结尾。
当length=0x8?时,表示length使用长码,低7位表示长码的八元组数量。
当length为其他值时,表示length使用短码,该八元组就是具体长度。
07

Value

value为TLV结构中的具体数据,该数据既可以是表示特定内容的数据,也可以嵌套的TLV结构。根据tag的不同,Value有着不同的表现形式。

EXPLICIT和IMPLICIT关键字

默认情况下,大部分的asn1定义最终都是由Universal类属中的基础类型定义。

 

当使用EXPLICITIMPLICIT关键字修饰时,表示使用中括号[]中指定的tag来描述该定义。

 

EXPLICITIMPLICIT关键字的区别在于,前者直接使用中括号[]中的tag的替换原数据的tag,后者在原数据前额外增加新的tag,而原来的tag保留不变。

 

EXPLICITIMPLICIT关键字默认使用Context-specific作为cls,此外,可以通过PRIVATEAPPLICATION显示指定cls。

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# !/usr/bin/env python3
# -*- coding:utf-8 -*-
 
import asn1tools
 
asn_def = "TEST DEFINITIONS ::= BEGIN\n"\
              "Test ::= SEQUENCE\n"\
              "{\n"\
                  "val1 INTEGER,\n"\
                  "val2[0] IMPLICIT INTEGER,\n"\
                  "val3[1] EXPLICIT INTEGER,\n"\
                  "val4[PRIVATE 2] IMPLICIT INTEGER,\n"\
                  "val5[PRIVATE 3] EXPLICIT INTEGER\n"\
              "}\n"\
          "END"
 
asn_def = asn1tools.compile_string(asn_def, "der")
asn_res = asn_def.encode("Test", {"val1":10,"val2":10,"val3":10,"val4":10,"val5":10})
print(asn_res.hex().upper())

python .\test_asn.py
301302010A80010AA10302010AC2010AE30302010A

30 13 #cls=0(Universal) tag=16(SEQUENCE) len=19
02 01 0A #正常情况:cls=0(Universal) tag=2(INTEGER) len=1 data=10
80 01 0A #加IMPLICIT修饰符并使用tag=0描述该定义:cls=2(Context-specific) tag=0 len=1 data=10
A1 03 #加EXPLICIT修饰符,在原来的数据前额外添加tag:cls=2(Context-specific) tag=1 len=3
02 01 0A #与正常情况的数据相同,cls=0(Universal) tag=2(INTEGER) len=1 data=10
C2 01 0A #同时指定cls和tag,cls=3(Private) tag=2 len=1 data=10
E3 03 #cls=3(Private) tag=3 len=3
02 01 0A #与正常情况的数据相同,cls=0(Universal) tag=2(INTEGER) len=1 data=10

参考资料

asn.1 格式学习
ASN/1 TLV

开始分析

asn1节点

这里先放上一节的流程图,在sub_77A950中可以看到asn1码流的解析。
02
每个asn1类型被定义为一个结构体节点,一开始是无法准确地知道每个字段的含义。通过相关查找,确认这些节点都是在github上的开源代码asn1c-0.9.26中定义。于是,我们对这些asn1节点有了较为清晰的了解。
01

获取所有asn1节点

通过观察asn1结构体节点,可以发现一般情况下,name字段和xml_tag字段指向同一个字符串,并且所有的节点都在data段内。我们可以在data段找两个即相邻又相同的指针,并且该指针指向的内容同样在data段内。节点之间通过elements字段关联,利用elements,我们可以为这些节点建立树状关系或层级关系,甚至可以恢复出整个asn1定义。下图LIF的asn1定义。

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 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 ::= SEQUENCE
{
    creator-name[PRIVATE 181] IMPLICIT UTF8String,
    creator-version[PRIVATE 165] IMPLICIT Format-Version,
    required-version[PRIVATE 122] IMPLICIT Format-Version
}
Format-Version ::= 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 ::= SEQUENCE
{
    box-time[PRIVATE 178] IMPLICIT Seconds-Since-2000,
    certified-time[PRIVATE 179] IMPLICIT Seconds-Since-2000
}
Seconds-Since-2000 ::= INTEGER
License-Description ::= 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 ::= INTEGER
Binding-Scheme ::= SEQUENCE
{
    cmact-id[PRIVATE 148] IMPLICIT CmAct-ID,
    telephone-id[PRIVATE 127] IMPLICIT Telephone-ID,
    binding-method[PRIVATE 128] EXPLICIT Binding-Method
}
CmAct-ID ::= IA5String
Telephone-ID ::= 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 ::= SEQUENCE
{
    heuristic[PRIVATE 31] IMPLICIT UInt8,
    redundancy-level[PRIVATE 130] IMPLICIT Redundancy-Level
}
Redundancy-Level ::= INTEGER
 
CustomBinding-Parameters ::= IA5String
DCBN-Parameters ::= 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 ::= SEQUENCE
{
    allow-vm[PRIVATE 219] IMPLICIT BOOLEAN,
    allow-reimport[PRIVATE 220] IMPLICIT BOOLEAN
}
Mask ::= INTEGER
 
END

解析asn1码流

有了这些节点和节点关系,我们就可以用它来解析码流了。接下来我们就来看看LIF文件里面到底有什么东西。先说结论吧,LIF文件包含一段LIF-content、两个证书和一段签名值。其中LIF-content包含一些授权信息和一些限制条件。两份证书和签名值用于验证LIF文件是否被修改。
以下是我使用asn1tools解析的Terra2314.WibuCmLIF(这个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
<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>

后续

接下来将会详细讲解如何使用asn1tools解析文件后缀为WibuCmLIFWibuCmRaCWibuCmRaU,并讲述其中几个关键密钥的生成和使用。


[2023春季班]《安卓高级研修班(网课)》月薪两万班招生中~

最后于 2022-12-15 20:51 被bluefish蓝鱼编辑 ,原因: 新增asn1码流解析
上传的附件:
收藏
点赞1
打赏
分享
最新回复 (3)
雪    币: 180
活跃值: 活跃值 (119)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wcdabcd 活跃值 2022-10-9 22:15
2
0
后续有windows平台的?
雪    币: 7073
活跃值: 活跃值 (3751)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
bluefish蓝鱼 活跃值 2022-10-15 16:02
3
0
wcdabcd 后续有windows平台的?
主要在linux平台逆向,后续应该不会在windows平台重新弄了
雪    币: 180
活跃值: 活跃值 (119)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wcdabcd 活跃值 2022-10-16 09:21
4
0
什么时候讲讲后续内容?
游客
登录 | 注册 方可回帖
返回