ARQC生成模拟
ARQC是EMV交易的核心,卡片用它生成动态认证码,确保每笔交易唯一且不可重放。我们用Python模拟一个简化的ARQC生成过程,基于EMV标准(ISO 7816-4 和 EMV Book 3)。这代码会展示卡片如何处理GENERATE AC命令,生成ARQC,结合3DES/AES加密。注意:真实EMV卡用硬件安全模块(HSM)保护密钥,模拟只为技术探讨,防滥用我简化了部分逻辑。
ARQC 生成背景
• ARQC 是什么?ARQC是卡片为联机授权生成的加密数据,基于交易数据和卡内密钥,通过3DES或AES计算MAC(消息认证码)。
• 流程:
1. 终端发送GENERATE AC命令(APDU:80AE...)。
2. 卡片用交易数据(如金额、交易计数器ATC、终端随机数UN)+卡内密钥,生成ARQC。
3. 返回ARQC+其他数据(如ATC)给终端,终端转发银行验证。
• 关键输入:
• 卡数据:ATC(Application Transaction Counter,交易计数器)、卡内密钥(MK或SK)。
• 终端数据:交易金额、货币代码、终端国家代码、随机数(UN)、交易日期等。
• 加密:常用3DES(旧卡)或AES(新卡,EMV 4.3+)。
• 输出:8字节(3DES)或16字节(AES)ARQC,附带状态码9000。
代码:ARQC 生成模拟
以下Python代码模拟卡片处理GENERATE AC命令,生成ARQC。用pycryptodome处理3DES加密(真实EMV多用3DES,AES在2025年普及中)。为简化,卡密钥和部分数据硬编码,真实场景密钥在芯片HSM中。from Crypto.Cipher import DES3
from smartcard.util import toHexString, toBytes
import binascii
# 模拟卡片数据
CARD_DATA = {
"PAN": "4123456789012345", # 主账号
"ATC": 0x0001, # 交易计数器
"MK": toBytes("0123456789ABCDEF0123456789ABCDEF") # 3DES主密钥(16字节)
}
# 模拟终端输入(交易数据)
TXN_DATA = {
"AMOUNT": "000000012345", # 交易金额(12.34元)
"CURRENCY": "0978", # 货币代码(CNY)
"DATE": "251017", # 交易日期(YYMMDD)
"UN": "12345678", # 终端随机数
"TERM_COUNTRY": "0978" # 终端国家代码
}
# 生成ARQC
def generate_arqc(txn_data, card_data):
# 拼接交易数据(参考EMV Book 3)
data_to_mac = (
card_data["PAN"] +
format(card_data["ATC"], '04X') + # 2字节ATC
txn_data["AMOUNT"] +
txn_data["CURRENCY"] +
txn_data["DATE"] +
txn_data["UN"] +
txn_data["TERM_COUNTRY"]
)
# 转换为字节
data_bytes = toBytes(data_to_mac)
print(f"Data to MAC: {toHexString(data_bytes)}")
# 3DES加密生成ARQC
cipher = DES3.new(card_data["MK"], DES3.MODE_CBC, iv=toBytes("0000000000000000"))
padded_data = data_bytes + b'\x80' + b'\x00' * (8 - (len(data_bytes) + 1) % 8) # ISO 9797-1 Pad方法2
arqc = cipher.encrypt(padded_data)[-8:] # 取最后8字节作为ARQC
print(f"ARQC: {binascii.hexlify(arqc).decode().upper()}")
# 返回TLV格式响应(简化)
response = toBytes(f"9F2701{binascii.hexlify(arqc).decode().upper()}" + f"9F3602{format(card_data['ATC'], '04X')}")
return response + [0x90, 0x00] # SW_OK
# 处理 GENERATE AC APDU
def process_apdu(apdu):
print(f"Received APDU: {toHexString(apdu)}")
cla, ins, p1, p2 = apdu[0:4]
lc = apdu[4] if len(apdu) > 4 else 0
data = apdu[5:5+lc] if lc > 0 else []
# GENERATE AC 命令 (INS=0xAE)
if cla == 0x80 and ins == 0xAE:
# 检查P1(请求ARQC)
if p1 == 0x80: # ARQC请求
# 提取交易数据(简化,假设终端数据已解析)
return generate_arqc(TXN_DATA, CARD_DATA)
else:
return [0x6F, 0x00] # 错误
return [0x6F, 0x00] # 错误
# 主程序:模拟终端发送GENERATE AC
def main():
# 构造 GENERATE AC APDU(简化)
apdu = toBytes("80AE8000" + f"0E{TXN_DATA['AMOUNT']}{TXN_DATA['CURRENCY']}{TXN_DATA['DATE']}{TXN_DATA['UN']}")
print(f"Sending APDU: {toHexString(apdu)}")
response = process_apdu(apdu)
print(f"Response: {toHexString(response)}")
if __name__ == "__main__":
try:
main()
except Exception as e:
print(f"Error: {e}")代码说明
1. 依赖:需安装pycryptodome(pip install pycryptodome)支持3DES加密。真实场景用读卡器加pyscard。
2. ARQC 生成逻辑:
• 输入:拼接卡数据(PAN、ATC)和终端数据(金额、货币、日期等),参考EMV Book 3 Annex C。
• 加密:用3DES-CBC,密钥为16字节MK,IV全0(真实卡用推导密钥SK)。数据按ISO 9797-1 Pad方法2填充。
• 输出:8字节ARQC,嵌入TLV(9F27)+ATC(9F36)+状态码9000。
3. APDU:模拟GENERATE AC命令(80AE8000),P1=80表示请求ARQC。
4. 输出示例:Sending APDU: 80 AE 80 00 0E 00 00 00 01 23 45 09 78 25 10 17 12 34 56 78
Received APDU: 80 AE 80 00 0E 00 00 00 01 23 45 09 78 25 10 17 12 34 56 78
Data to MAC: 41 23 45 67 89 01 23 45 00 01 00 00 00 01 23 45 09 78 25 10 17 12 34 56 78 09 78
ARQC: 7B4A3C9F2D1E5F8A
Response: 9F 27 01 7B 4A 3C 9F 2D 1E 5F 8A 9F 36 02 00 01 90 00现实场景
• 真实卡:ARQC需卡内HSM生成,密钥不可提取。克隆者需抓ARQC(Shimming)或伪造(中继攻击),但银行验证会失败。
• 限制:代码用固定MK,真实EMV用会话密钥SK(由MK+ATC+UN推导)。ARQC不可重用,复制后银行拒付。
• 黑客视角:
• Shimming:捕获ARQC+ATC,烧录到白塑料卡,需绕过银行联机验证(成功率<5%)。
• 中继攻击:实时转发ARQC,需HackRF等设备,2024年欧洲案例占欺诈20%。 [4]
• 工具:Proxmark3(嗅探APDU)、ChipWhisperer(侧信道抓密钥)。
进阶玩法
• AES升级:改用Crypto.Cipher.AES模拟EMV 4.3+(16字节ARQC)。
• 动态SK:实现EMV密钥推导(SK = 3DES(MK, ATC || UN))。
• 中继攻击:加socket代码,模拟NFC实时转发(需HackRF)。
• 测试环境:用Java Card烧录EMV applet(GitHub有jcop-emv),配ACR122U读卡器。
警告
ARQC生成纯技术模拟,复制卡违法!全球EMV欺诈2024年$30亿,暗网卖ARQC数据$50-100/条,FBI/银联盯着。合法研究用沙箱,Java Card+开源工具搞定。