安全通道协议详解

人越长大,就越习惯压抑内心的真实感受,不再放声大哭放声大笑,什么都只是淡淡的点到为止。好像越来越没有什么事,可以伤心到落泪,再也找不出,释放伤感的出口

Posted by yishuifengxiao on 2025-11-13

安全通道协议详解

SCP(Secure Channel Protocol,安全通道协议)系列是智能卡(尤其是SIM卡、UICC)与外界(如手机、OTA服务器)建立安全通信的核心机制。这些协议解决了同一个核心问题:如何在不可信的信道上,安全地传输指令和数据

根据应用场景和协议栈的不同,SCP主要分为两大类:一类用于本地安全通道(SCP02、SCP03),另一类用于远程文件管理(SCP80、SCP81)。

下面的表格对比了这四种协议的核心特性:

协议 核心用途 安全机制 典型应用场景
SCP02 本地安全通道 (GlobalPlatform) 3DES对称密钥、MAC校验、可选加密 发卡后初始化、敏感文件写入(如网络锁定、IMSI更新)
SCP03 本地安全通道 (GlobalPlatform) AES对称密钥(更安全)、多样化派生密钥 高安全等级的个人化操作(如eSIM配置文件下载、支付应用安装)
SCP80 远程文件管理 (OTA) SMS-CB、USSD为载体,分段传输,安全包结构 通过短信发送小数据包(如运营商服务菜单更新、开机欢迎语)
SCP81 远程文件管理 (OTA) CAT_TP (BIP) 或 HTTPS为载体,TCP/IP通道 通过BIP通道进行大数据量交互(如手机营业厅应用下载、大文件更新)

SCP02 与 SCP03:本地安全通道

SCP02和SCP03主要用于卡和终端(或读卡器)之间的本地会话安全。它们通过“安全通道”的建立,确保后续发送的APDU指令(如写入关键文件)不被窃听或篡改。

SCP02

这是GlobalPlatform(全球平台组织)定义的第一代安全通道协议,基于3DES算法。

  • 主要场景:卡片生命周期管理,尤其是在发卡后对卡片进行初始化和个人化操作。
  • 核心指令INITIALIZE UPDATEEXTERNAL AUTHENTICATE

APDU指令示例:建立SCP02安全通道的过程

第一步:初始化更新 (INITIALIZE UPDATE)
终端发送此指令,向卡片发起建立安全通道的请求,并携带随机数等挑战信息。

# CLA INS P1 P2 Lc 数据域
00 70 00 00 10 数据域(16字节,通常是挑战随机数)

第二步:外部认证 (EXTERNAL AUTHENTICATE)
卡片返回INITIALIZE UPDATE响应(包含卡片随机数、卡片密钥衍生数据等)。终端根据这些信息计算会话密钥,并发送EXTERNAL AUTHENTICATE进行认证。

# CLA INS P1 P2 Lc 数据域 (包含加密后的主机认证数据)
00 82 00 00 10 数据域(16字节)

成功执行后,终端和卡片之间就建立了一个安全通道。后续的PUT DATASTORE DATA等指令可以带上安全报文(即加密和MAC校验值)通过该通道发送。

SCP03

SCP03是SCP02的升级版,基于更先进的AES算法,并支持多种密钥派生模式,安全性更高。

  • 主要场景:eSIM(嵌入式SIM卡)配置文件的下载、金融级支付应用的安装等高安全等级场景。
  • 核心指令INITIALIZE UPDATEEXTERNAL AUTHENTICATE(指令代码与SCP02相同,但数据结构不同)。

与SCP02相比,SCP03的INITIALIZE UPDATE指令在数据域中包含了更丰富的参数,用于协商使用AES算法。后续的安全报文也使用AES-CMAC和AES加密,而非3DES。


SCP80 与 SCP81:远程文件管理

SCP80和SCP81主要用于运营商对已发行的SIM卡进行远程管理(OTA,Over-The-Air)。终端(手机)在这里扮演一个透明的传输通道角色。

SCP80

SCP80利用短信或USSD等无连接通道传输数据。由于短信有长度限制(通常140字节),数据包需要分段、重组和确认。

  • 主要场景:发送小数据量、非实时的管理指令,如更新运营商服务菜单(STK菜单)、修改开机问候语、更新禁用网络列表等。
  • 载体:SMS-CB(小区广播)、SMS-PP(点对点短信)、USSD。
  • 核心机制:将应用层数据封装成短消息传输协议数据单元,然后通过ENVELOPE (SMS-PP DOWNLOAD)ENVELOPE (USSD)指令送入SIM卡。

APDU指令示例:手机将接收到的OTA短信转发给SIM卡

手机收到一条特殊格式的OTA短信(例如用于更新SIM服务菜单),手机会将其解析为APDU指令发给SIM卡处理。

# CLA INS P1 P2 Lc 数据域 (数据域包含封装好的SMS-PP TPDU)
80 00 00 00 00 数据域(包含完整的OTA短信内容)

这条指令的CLA常为8000INS00(ENVELOPE)。数据域里封装的是一个TPDU(传输协议数据单元),里面才包含着真正的SCP80安全包。

SCP81

SCP81利用CAT_TP (Card Application Toolkit Transport Protocol)BIP (Bearer Independent Protocol) 等基于IP的通道传输数据。

  • 主要场景:需要大数据量、实时性交互的场景。比如通过手机自带的“运营商服务”应用(如中国移动的“我的SIM”应用)去下载一个几MB大小的文件,或者进行在线话费查询。
  • 载体:BIP (TCP/IP)、CAT_TP、HTTPS。
  • 核心机制:SIM卡扮演网络客户端角色,终端为其提供一个数据管道。

APDU指令示例:建立BIP通道和发送数据

SCP81的交互过程远比SCP80复杂,涉及终端和SIM卡之间一系列复杂的APDU指令交互。

第一步:打开BIP通道
SIM卡主动通过FETCH指令要求终端打开一个数据通道(如GPRS或Wi-Fi)。

# 终端 -> 卡: 告知卡有数据可获取
80 10 00 00 00 # 这是FETCH指令的通用形式
# 卡 -> 终端: 响应,要求打开一个到特定服务器地址和端口的通道
# 响应数据如: 41 41 02 15 ... (表示OPEN CHANNEL,承载类型为GPRS等)

第二步:数据交换
通道建立后,SIM卡再次通过FETCH指令发送HTTP请求报文,终端接收后将报文发送到网络服务器,并将服务器的响应通过TERMINAL RESPONSE指令回传给SIM卡。

# 卡 -> 终端: 发送一个FETCH请求,获取待发送的数据
80 10 00 00 00
# 终端 -> 卡: 通过TERMINAL RESPONSE发送HTTP请求包 (这是SCP81的数据承载)
80 12 00 00 00 数据域(HTTP GET /update 1.1 ...)

在整个SCP81过程中,APDU指令主要起到一个“指挥”和“搬运工”的作用,实际的数据内容(如HTTP报文)被封装在APDU的数据域中。

总结

  • SCP02/SCP03 关注的是本地接口的安全,解决的是“本地连接如何信任”的问题。区别在于算法和安全性等级。
  • SCP80/SCP81 关注的是远程传输的安全,解决的是“通过手机网络如何管理”的问题。区别在于传输载体和数据量的大小。

加密过程详解

SCP03的“加密”和“MAC计算”是它保证数据机密性和完整性的核心技术。简单来说,加密使用的是AES算法,确保数据不被窃听;而MAC计算使用的是AES-CMAC算法,确保数据不被篡改

在SCP03安全通道建立后,通信双方(如手机和SIM卡)会协商出三个会话密钥,它们分别承担不同的安全职责:

密钥名称 全称及用途 算法
S-ENC 会话加密密钥:用于对发送的命令数据进行加密,保证机密性。 AES(通常为128位或256位)
S-MAC 会话命令MAC密钥:用于为发送的命令计算MAC,保证命令的完整性,并验证其来源。 AES-CMAC
S-RMAC 会话响应MAC密钥:用于为收到的响应计算MAC,保证响应的完整性,并验证其来源。 AES-CMAC

在安全通信阶段,发送方(通常是终端)会使用S-ENCS-MAC对APDU指令进行处理,接收方(通常是卡片)则使用对应的密钥进行解密和校验。其核心流程如下:

flowchart TD
A[原始APDU指令] --> B{是否需要加密?}

B -- 是 --> C[使用S-ENC密钥<br>进行AES-CBC加密]
B -- 否 --> D[保持明文数据]

C --> E[组合数据域]
D --> E

E --> F[计算MAC]
F --> G[使用S-MAC密钥<br>进行AES-CMAC计算]
G --> H[将MAC附加到指令末尾]

H --> I[组装并发送最终的<br>安全APDU指令]

加密过程详解

当需要保护数据内容的机密性时(例如写入密钥或敏感个人信息),就会对APDU指令的数据域进行加密。

  1. 算法:使用AES算法,通常采用CBC模式。需要初始向量(IV),在SCP03中,IV通常被固定为16字节的0x00
  2. 填充:由于AES是分组密码,要求输入数据长度是16字节的整数倍。因此,加密前需要对明文数据使用ISO/IEC 9797-1 Padding Method 2进行填充,即在数据后依次添加0x80和若干个0x00,直至长度满足要求。
  3. 加密对象:仅加密APDU指令的数据域(Data Field)。指令的头部(CLA, INS, P1, P2)是不加密的,因为它们需要被卡片路由和处理。
  4. 指令标识:启用加密后,APDU指令的CLA字节通常会从 0x000x80 变为 0x84,用于告知卡片“本条指令的数据部分是加密的”。

MAC计算详解

MAC用于确保指令的完整性和真实性,防止指令在传输过程中被篡改。

  1. 算法:使用AES-CMAC算法。这是一种基于AES的、更安全的MAC算法。
  2. 计算范围:需要计算整个APDU指令中除MAC自身以外的所有部分,包括CLA, INS, P1, P2, Lc(长度)和加密后的Data(数据域)
  3. 链式依赖(关键!):为了防止重放攻击并确保指令的顺序性,SCP03引入了MAC Chaining Value机制。简单来说,当前指令的MAC计算依赖于上一条指令的部分计算结果。因此,多条指令必须按顺序发送和处理,不能乱序
  4. 截断:AES-CMAC算法完整计算出的结果是16字节。但在APDU指令中,为了节省空间,只会取前8个字节附加在指令末尾作为最终的MAC值。

一个完整的APDU指令示例

假设有一条明文指令 00 A4 00 00 02 3F00(选择MF文件)。启用SCP03的安全报文后,它会被封装成类似下面的样子:

# 格式: CLA INS P1 P2 Lc 数据域(加密后的数据) MAC(8字节)
84 A4 00 00 22 加密后的数据(34字节) C36703B133EE13A8
  • CLA (0x84):从 0x00 变为 0x84,表示这是一个启用了安全报文(加密+MAC)的指令。
  • Lc (0x22):长度字段,它现在表示“加密后的数据域 + MAC”的总长度。
  • 数据域 (34字节):原本的 3F00 经过填充、加密后,变成了一个很长的密文。
  • MAC (C36703B133EE13A8):卡片的COS会使用S-MAC密钥,按照同样的规则重新计算MAC,并与指令携带的8字节MAC进行比对。只有比对成功,指令才会被执行。

关键操作注意事项

  1. 初始化是前提:所有上述加密和MAC计算,都必须在成功执行 INITIALIZE UPDATEEXTERNAL AUTHENTICATE 指令、建立安全通道并派生会话密钥之后才能进行。
  2. 脚本链接:在处理多条指令时,必须使用“脚本链接”机制,告诉卡片所有指令都属于同一个会话。这通常通过在指令前添加特定的TLV标签(如 AE80830101 表示指令1)来实现。
  3. 响应也要验证:卡片返回的响应APDU同样会受到保护。终端需要使用 S-RMAC 密钥来验证响应中的MAC,确保响应没有被篡改。

加密和MAC计算细节

这个过程在安全通道建立之后进行,假设已经成功执行了INITIALIZE UPDATEEXTERNAL AUTHENTICATE,派生出了三个会话密钥:S-ENC(加密密钥)、S-MAC(命令MAC密钥)和S-RMAC(响应MAC密钥)。


会话密钥(示例值)

为便于演示,假设以下128位AES密钥(十六进制):

密钥 值(16字节)
S-ENC 404142434445464748494A4B4C4D4E4F
S-MAC 505152535455565758595A5B5C5D5E5F
S-RMAC 606162636465666768696A6B6C6D6E6F

实际场景中,这些密钥是通过卡片和终端交换的随机数,结合主密钥派生的。


加密过程(AES-CBC)

加密仅应用于APDU指令的数据域(Data Field),目的是保证机密性。

步骤:

  1. 明文数据:待加密的原始数据(例如选择文件的AID或写入的个人化数据)。
  2. 填充(ISO/IEC 9797-1 Method 2)
    • 在数据后添加一个字节0x80
    • 然后添加足够的0x00,使总长度为16字节的整数倍。
    • 如果原始数据长度已经是16字节的倍数,则仍需添加16字节:0x80后跟15个0x00
  3. IV:初始向量固定为16字节全0x00
  4. 加密:使用AES-128-CBC模式(SCP03通常支持AES-128,也可用AES-256,这里以AES-128为例)对填充后的数据进行加密。

示例

假设要发送一条选择MF(主文件)的APDU指令,原始指令为:

00 A4 00 00 02 3F00

明文数据域(3F00)长度为2字节。

填充:

  • 添加0x803F00 80
  • 0x00至16字节 → 3F00 80 00 00 00 00 00 00 00 00 00 00 00 00 00
  • 最终16字节:3F 00 80 00 00 00 00 00 00 00 00 00 00 00 00 00

AES-CBC加密(IV=全0):

使用密钥404142434445464748494A4B4C4D4E4F加密后,得到16字节密文(以C1C16表示)。假设计算结果为:

3A 92 3F 8C 6F 9E 4C B9 7E 2A D3 8E 1B 5C 9F 4E

(这仅为示例,实际结果取决于密钥和算法实现)


MAC计算过程(AES-CMAC)

MAC用于保证指令的完整性和真实性,防止重放攻击,SCP03中采用链式MAC(MAC Chaining)。

步骤:

  1. 构建输入数据:需要计算MAC的数据包括:

    • 修改后的CLA(将原CLA的bit 2设为1,例如0084
    • INSP1P2
    • Lc(表示密文长度 + MAC长度,即最终指令数据域的总字节数)
    • 密文(即上述加密后的数据)
    • 注意:MAC本身不参与计算。
  2. 链值(Chaining Value)

    • 对于第一条安全指令,链值为16字节0x00
    • 对于后续指令,链值为上一条指令计算出的16字节MAC值(即完整的AES-CMAC结果,非截断)。
    • 链值参与MAC计算,使得指令顺序不可调换。
  3. 计算MAC:使用AES-CMAC算法,输入为(链值 || 上述输入数据),输出16字节MAC值。

  4. 截断:取前8字节作为最终附加在指令中的MAC。

示例(接上一条SELECT MF指令):

已得到密文(16字节),现在构建MAC输入。

修改CLA:

原CLA为00,启用安全报文后改为84(表示加密+MAC)。

计算Lc:

  • 密文长度 = 16字节
  • MAC长度 = 8字节
  • 总数据域长度 = 16 + 8 = 24字节 = 0x18

构造MAC输入数据:

CLA INS P1 P2 Lc 密文
84 A4 00 00 18 3A 92 3F 8C 6F 9E 4C B9 7E 2A D3 8E 1B 5C 9F 4E

计算链值:

因为是第一条安全指令,链值 = 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

AES-CMAC计算:

输入 = 链值 || 上述数据,使用S-MAC密钥505152535455565758595A5B5C5D5E5F,得到16字节CMAC结果。假设结果为:

7B D6 2F 1A 3E 9C 5B D8 0F 4A 3E 7C D1 8F 2B 6E

截取前8字节作为MAC:

7B D6 2F 1A 3E 9C 5B D8


构建最终安全APDU

将加密后的密文和MAC拼接,形成数据域,并组装APDU:

84 A4 00 00 18 密文(16字节) MAC(8字节)

即:

84 A4 00 00 18 3A 92 3F 8C 6F 9E 4C B9 7E 2A D3 8E 1B 5C 9F 4E 7B D6 2F 1A 3E 9C 5B D8

卡片收到后,会先用S-MAC验证MAC,成功后再用S-ENC解密数据域(去除MAC部分),得到明文。


多条指令时的链值更新

假设要发送第二条安全指令,链值应为上一条指令的完整16字节CMAC结果(即7B D6 2F 1A 3E 9C 5B D8 0F 4A 3E 7C D1 8F 2B 6E)。计算第二条指令的MAC时,输入数据最前面先拼接这个链值,然后再接CLA密文

这种链式机制强制了指令的顺序性,有效防止重放攻击。


响应报文的MAC验证

卡片返回的响应(Status Word前)也可能包含一个8字节的MAC,终端需要用S-RMAC密钥按相同规则计算并验证。计算方法类似,但输入数据为响应报文的状态码之前的部分。


注意事项

  • CLA字节规则:当使用加密+MAC时,CLA通常设为0x84(即原CLA的bit 2置1)。若仅使用MAC而不加密,则设为0x04(数据域为明文+MAC)。
  • 长度字段Lc必须准确反映加密数据+MAC的总长度,否则卡片会报长度错误。
  • 密钥长度:SCP03支持AES-128、192、256,实际使用取决于卡片和终端的协商结果,一般在INITIALIZE UPDATE时确定。
  • IV的变体:部分实现可能使用全0之外的IV,但SCP03标准明确CBC模式IV为全0。

INITIALIZE UPDATEEXTERNAL AUTHENTICATE

接下来详细解析 SCP03 安全通道建立的核心步骤:INITIALIZE UPDATEEXTERNAL AUTHENTICATE。这两个指令完成会话密钥的派生和双向认证,为后续的安全报文传输奠定基础。


前提条件

  • 卡片已经预置了与终端共享的静态主密钥(通常是AES-128/192/256,如KENCKMACKRMAC,但实际SCP03使用一对静态主密钥,分别用于加密和MAC,并通过KDF派生出会话密钥)。
  • 终端知道这些主密钥,并拥有卡片的识别信息(如卡片序列号ICCID、ISD AID等)。
  • 支持SCP03的卡片和终端都实现了GlobalPlatform规范中定义的SCP03协议。

INITIALIZE UPDATE(初始化更新)

这是安全通道建立的第一步,终端向卡片发起挑战,卡片返回随机数和派生数据。

指令格式

CLA INS P1 P2 Lc 数据域
84 70 00 00 [Lc] [数据]
  • CLA: 84 表示启用安全报文(安全通道相关指令)。
  • INS: 70INITIALIZE UPDATE 的指令码。
  • P1, P2: 通常为 00 00
  • Lc: 数据域长度,取决于数据域中的内容。
  • 数据域:包含终端的挑战值(Host Challenge)和可选参数。

数据域结构(TLV格式)

标签 长度
80 8 Host Challenge(终端随机数,8字节)
81 1 Key Diversification Data Length(可选)
82 可变 Key Diversification Data(可选,用于密钥派生)
83 2 Key Version Number(可选,密钥版本号)

实际规范要求至少包含 80 标签的终端挑战值。

示例指令(假设终端产生8字节挑战 1122334455667788,无其他可选数据):

84 70 00 00 0C 80 08 11 22 33 44 55 66 77 88

解释:84 70 00 00 头部,Lc=0C(12字节),数据域为 80 08 后跟8字节挑战值。

卡片响应

卡片处理 INITIALIZE UPDATE 后,返回响应数据(TLV格式),通常包含:

标签 长度
80 8 Card Challenge(卡片随机数,8字节)
81 可变 Card Cryptogram(卡片密码,16字节或更多)
82 可变 Key Diversification Data(密钥派生数据,可选)
83 2 Key Version Number(可选)
84 1 Secure Channel Protocol Options(SCP选项,指示使用的算法、密钥长度等)

其中 Card Cryptogram 是使用主密钥对某些数据计算得到的,用于终端验证卡片身份。

响应示例(假设卡片返回8字节挑战 AABBCCDDEEFF0011,Card Cryptogram 16字节,SCP Options = 80 表示AES-128):

80 08 AA BB CC DD EE FF 00 11
81 10 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10
84 01 80

(实际响应中每个TLV连续排列,这里为了清晰分行)


会话密钥派生(Key Derivation)

终端收到卡片的响应后,结合自己的主密钥和交换的随机数,派生出三个会话密钥:S-ENC(加密密钥)、S-MAC(命令MAC密钥)、S-RMAC(响应MAC密钥)。

SCP03的密钥派生使用 KDF (Key Derivation Function),具体为:KDF(C, L),其中 C 是派生输入(包含卡挑战、主机挑战等),L 是期望密钥长度。通常基于 AES-CMACAES-CBC-MAC 实现。

派生步骤(简化)

  1. 构建 派生字符串

    D = 00 00 00 01  ||  卡挑战(8字节)  ||  主机挑战(8字节)  ||  00 00 00 02  ||  卡挑战  ||  主机挑战  || ...(根据需要的密钥数量重复)

    实际GlobalPlatform规范有明确的结构,包含计数器、上下文、算法标识等。

  2. 使用静态主密钥(如 KMAC)对派生字符串计算 AES-CMAC,得到的结果作为会话密钥。

  3. 重复该过程(改变计数器)得到不同用途的密钥。

示例(假设简化派生)

假设主密钥为 404142434445464748494A4B4C4D4E4F,卡挑战 CARD_CH,主机挑战 HOST_CH。派生S-ENC、S-MAC、S-RMAC的过程略复杂,但最终终端和卡片会通过相同算法得到完全一致的三个会话密钥。


EXTERNAL AUTHENTICATE(外部认证)

终端利用派生出的会话密钥构造认证数据,发送给卡片完成相互认证。

指令格式

CLA INS P1 P2 Lc 数据域
84 82 00 00 [Lc] [数据]
  • CLA: 84
  • INS: 82EXTERNAL AUTHENTICATE
  • P1, P2: 00 00
  • 数据域:包含终端认证数据(TLV格式),可能还包含安全通道选项。

数据域结构(TLV)

标签 长度
80 16 Host Cryptogram(终端密码,16字节)
81 可变 Secure Channel Protocol Options(可选)

Host Cryptogram 的计算:使用 S-MAC 密钥对某些数据(如卡挑战、主机挑战、密钥派生数据等)计算 AES-CMAC 得到16字节结果,取前16字节作为Host Cryptogram。

示例指令(假设Host Cryptogram为 1234567890ABCDEF1234567890ABCDEF):

84 82 00 00 12 80 10 12 34 56 78 90 AB CD EF 12 34 56 78 90 AB CD EF

卡片响应

卡片收到 EXTERNAL AUTHENTICATE 后,使用自身的会话密钥验证Host Cryptogram。如果验证通过,卡片返回一个 Card Authentication Cryptogram(卡认证密码),用于终端验证卡片(可选)。如果验证失败,卡片返回错误状态码。

响应示例(假设卡片返回16字节卡认证密码):

80 10 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF

这个卡认证密码是卡片使用 S-RMAC 对某些数据计算得到的,终端可以用S-RMAC验证,完成双向认证。


安全通道建立完成

执行完 EXTERNAL AUTHENTICATE 并验证响应后,安全通道建立。此后,终端和卡片可以使用派生出的会话密钥对后续APDU指令进行加密和MAC保护(如前面所述)。


SCP03 与 SCP02 的主要区别

项目 SCP02 SCP03
算法 3DES AES
密钥长度 112/168位 128/192/256位
会话密钥派生 基于3DES的特定KDF 基于AES-CMAC的KDF,支持更多衍生数据
指令数据域结构 非TLV,固定顺序 TLV结构,扩展性强
链式MAC 基于3DES CBC-MAC 基于AES-CMAC,链值机制更安全
会话密钥数量 3个(加密、MAC、RMAC) 3个(S-ENC、S-MAC、S-RMAC)

实际注意事项

  • 版本协商INITIALIZE UPDATE 的数据域中可能包含密钥版本号、SCP选项,用于协商算法强度。
  • 卡片状态:安全通道建立后,卡片内部状态机进入安全模式,后续指令必须携带正确的安全报文。
  • 多会话支持:卡片可能同时支持多个安全通道,通过上下文区分。
  • 错误处理:如果 INITIALIZE UPDATEEXTERNAL AUTHENTICATE 失败,卡片会返回特定状态码(如 6982 安全状态不满足,6A88 引用数据未找到等)。