securechannel.processSecurity(apdu) 中的错误 0x6700
Error 0x6700 in securechannel.processSecurity(apdu)
我想生成 gp 安全通道 01。我的踪迹是:
Send: 80 50 00 00 08 00 00 00 00 00 00 00 00
Recv: 00 00 00 00 00 00 00 00 00 00 FF 02 00 02 0E 5A 8F F4 57 DD 35 5C 49 A6 8B 15 E9 A5 9000
所以我有:
Card challenge= 00 02 0E 5A 8F F4 57 DD
Host challenge=00 00 00 00 00 00 00 00
根据 SPC01:image
Derivation data== 8F F4 57 DD 00 00 00 00 00 02 0E 5A 00 00 00 00
IV=0000000000000000
c_ENC: 404142434445464748494A4B4C4D4E4F
根据这个image和在线3Des
会话 s_ENC= C72F032C8BAD55D4D2579295CCF0A6CA
现在:
hot-auth_data = card challenge + host challenge + pad
host-auth= 00020E5A8FF457DD00000000000000008000000000000000
s_ENC=C72F032C8BAD55D4D2579295CCF0A6CA
IV=0000000000000000
===========
result= 93CC77E144488A031BFFCCC62EB3B5C233A485F8255FE90E
Host cryptogram= 33A485F8255FE90E
但是当我发送时:
848200000833A485F8255FE90E
我在方法 SDInstruction 中有错误 0x6700
短 len = sc.processSecurity(apdu);
public void process(APDU apdu) throws ISOException {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
switch (buffer[ISO7816.OFFSET_INS]) {
case ISO7816.INS_SELECT:
select();
return;
case INS_INIT_UPDATE:
case INS_EXT_AUTH:
SDInstruction(apdu);
break;
}
}
private void SDInstruction(APDU apdu)
{
byte[] buf = apdu.getBuffer();
byte cla = buf[ISO7816.OFFSET_CLA];
byte ins = buf[ISO7816.OFFSET_INS];
apdu.setIncomingAndReceive();
if(ins == INS_INIT_UPDATE)
sc = GPSystem.getSecureChannel();
short len = sc.processSecurity(apdu);
apdu.setOutgoing();
apdu.setOutgoingLength(len);
apdu.sendBytes(ISO7816.OFFSET_CDATA, (short) len);
}
根据 GlobalPlatform specification,EXTERNAL AUTHENTICATE 命令必须包括主机密码以及 MAC。两者都是 8 个字节长,因此,您的命令总共应为 16 个字节。
如果你想自己实现这个MAC值的生成,你可以按照GlobalPlatform spec中的描述来实现。但我建议您使用可用的开源实现。例如:GPJ 是 GlobalPlatform 规范的 Java 实现,具有您需要的所有命令。您可以查看 class GlobalPlatformService,您可以在其中找到安全通道协议的实现。 GPDroid (github.com/mobilesec/secure-element-gpdroid) 是这个项目在 Android.
上的包装器
您的卡正在使用 SCP02
而不是 SCP01
。
鉴于对 INITIALIZE UPDATE
命令的响应:
00 00 00 00 00 00 00 00 00 00 FF 02 00 02 0E 5A 8F F4 57 DD 35 5C 49 A6 8B 15 E9 A5 9000
突出显示的部分是 "Key Information",其中包含:
"Key Version Number" -- 在你的踪迹中 0xFF
"Secure Channel Protocol Identifier" -- 在你的轨迹中它是 0x02
表示 SCP02
请参阅 Global Platform Card Specification 以获取更多参考(描述 INITIALIZE UPDATE
命令的部分)。
因此您需要根据SCP02
.
与卡建立安全通道
一些额外的(随机)注释:
务必检查 "Card Recognition Data"(标签 '64'
)中编码的 "i"
安全通道参数嗯
你可能想看看方法GlobalPlatform.openSecureChannel() and the inner class GlobalPlatform.SCP0102Wrapper in the GlobalPlatformPro工具源代码
祝你好运!
我想生成 gp 安全通道 01。我的踪迹是:
Send: 80 50 00 00 08 00 00 00 00 00 00 00 00
Recv: 00 00 00 00 00 00 00 00 00 00 FF 02 00 02 0E 5A 8F F4 57 DD 35 5C 49 A6 8B 15 E9 A5 9000
所以我有:
Card challenge= 00 02 0E 5A 8F F4 57 DD
Host challenge=00 00 00 00 00 00 00 00
根据 SPC01:image
Derivation data== 8F F4 57 DD 00 00 00 00 00 02 0E 5A 00 00 00 00
IV=0000000000000000
c_ENC: 404142434445464748494A4B4C4D4E4F
根据这个image和在线3Des
会话 s_ENC= C72F032C8BAD55D4D2579295CCF0A6CA
现在:
hot-auth_data = card challenge + host challenge + pad
host-auth= 00020E5A8FF457DD00000000000000008000000000000000
s_ENC=C72F032C8BAD55D4D2579295CCF0A6CA
IV=0000000000000000
===========
result= 93CC77E144488A031BFFCCC62EB3B5C233A485F8255FE90E
Host cryptogram= 33A485F8255FE90E
但是当我发送时: 848200000833A485F8255FE90E 我在方法 SDInstruction 中有错误 0x6700 短 len = sc.processSecurity(apdu);
public void process(APDU apdu) throws ISOException {
if (selectingApplet()) {
return;
}
byte[] buffer = apdu.getBuffer();
switch (buffer[ISO7816.OFFSET_INS]) {
case ISO7816.INS_SELECT:
select();
return;
case INS_INIT_UPDATE:
case INS_EXT_AUTH:
SDInstruction(apdu);
break;
}
}
private void SDInstruction(APDU apdu)
{
byte[] buf = apdu.getBuffer();
byte cla = buf[ISO7816.OFFSET_CLA];
byte ins = buf[ISO7816.OFFSET_INS];
apdu.setIncomingAndReceive();
if(ins == INS_INIT_UPDATE)
sc = GPSystem.getSecureChannel();
short len = sc.processSecurity(apdu);
apdu.setOutgoing();
apdu.setOutgoingLength(len);
apdu.sendBytes(ISO7816.OFFSET_CDATA, (short) len);
}
根据 GlobalPlatform specification,EXTERNAL AUTHENTICATE 命令必须包括主机密码以及 MAC。两者都是 8 个字节长,因此,您的命令总共应为 16 个字节。
如果你想自己实现这个MAC值的生成,你可以按照GlobalPlatform spec中的描述来实现。但我建议您使用可用的开源实现。例如:GPJ 是 GlobalPlatform 规范的 Java 实现,具有您需要的所有命令。您可以查看 class GlobalPlatformService,您可以在其中找到安全通道协议的实现。 GPDroid (github.com/mobilesec/secure-element-gpdroid) 是这个项目在 Android.
上的包装器您的卡正在使用 SCP02
而不是 SCP01
。
鉴于对 INITIALIZE UPDATE
命令的响应:
00 00 00 00 00 00 00 00 00 00 FF 02 00 02 0E 5A 8F F4 57 DD 35 5C 49 A6 8B 15 E9 A5 9000
突出显示的部分是 "Key Information",其中包含:
"Key Version Number" -- 在你的踪迹中
0xFF
"Secure Channel Protocol Identifier" -- 在你的轨迹中它是
0x02
表示SCP02
请参阅 Global Platform Card Specification 以获取更多参考(描述 INITIALIZE UPDATE
命令的部分)。
因此您需要根据SCP02
.
一些额外的(随机)注释:
务必检查 "Card Recognition Data"(标签
'64'
)中编码的"i"
安全通道参数嗯你可能想看看方法GlobalPlatform.openSecureChannel() and the inner class GlobalPlatform.SCP0102Wrapper in the GlobalPlatformPro工具源代码
祝你好运!