C# PCSC-sharp 发送/接收带有数据的自定义命令
C# PCSC-sharp Send / Receive Custom Commands with Data
我正在开发 C# Java 卡(智能卡)程序,我正在尝试在 github.
上使用 PCSC-sharp 库
这是我请求的 "short / tl;dr" 版本:
PCSC-sharp 示例涵盖了 Iso7816 Case2Short。有人可以更正我下面的示例,或者提供一个 Iso7816 Case3Short(命令数据。无响应数据)和 Case4Short(命令数据。预期响应数据)的示例吗?
这是我请求的 "long" 版本:
在 Java 卡上,我同时使用标准和自定义 APDU 命令,并且我可以使用 python 脚本(使用智能卡库)成功调用这些命令。换句话说,我已经证明可以使用 Java 卡片命令。
我现在的目标是使用 PCSC-sharp 执行相同的命令,但是当我包含数据时我失败了(即 APDU LC > 0)。
这是 github 上的示例。请注意,我可以在仅更改 reader 名称、指令(select 文件而不是获取挑战)和 Le.
的情况下使用它
var contextFactory = ContextFactory.Instance;
using (var ctx = contextFactory.Establish(SCardScope.System)) {
using (var isoReader = new IsoReader(ctx, "ACME Smartcard reader",
SCardShareMode.Shared, SCardProtocol.Any, false)) {
var apdu = new CommandApdu(IsoCase.Case2Short, isoReader.ActiveProtocol) {
CLA = 0x00, // Class
Instruction = InstructionCode.GetChallenge,
P1 = 0x00, // Parameter 1
P2 = 0x00, // Parameter 2
Le = 0x08 // Expected length of the returned data
};
var response = isoReader.Transmit(apdu);
Console.WriteLine("SW1 SW2 = {0:X2} {1:X2}", response.SW1, response.SW2);
// ..
}
}
我的示例版本中的 APDU 转换为:
Send: 00 A4 00 00 00 00
Resp: 90 00
...这对我有用并且适用于 Case2Short(无数据,无响应)
我要重新创建的是两种不同类型的传输:
Case3Short(命令数据。无响应数据)
Send: 00 A4 04 00 06 01 02 03 04 05 06 00
Resp 90 00
这是我的代码:
private bool SendApduCase3()
{
var success = false;
DebugWriteLine("case3 start");
using (var isoReader = new IsoReader(td.context, td.name, SCardShareMode.Shared, SCardProtocol.T1, false))
{
DebugWriteLine("case3 command");
var commandApdu = new CommandApdu(IsoCase.Case3Short, isoReader.ActiveProtocol)
{
CLA = 0x00,
INS = 0xA4,
P1 = 0x04,
P2 = 0x00,
Data = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
Le = 0x00
};
DebugWriteLine("case3 transmit");
var response = isoReader.Transmit(commandApdu);
if ((response.SW1 == 0x90) && (response.SW2 == 0x00)) success = true;
}
DebugWriteLine("case3 " + success.ToString());
return (success);
}
...但它捕捉到命令并且从未将其发送到传输,而是 return 出现以下错误:
System.ArgumentException:
Iso7816-4 Case3Short does not expect any data fields in its return value and therefore has no bytes for Le
at PCSC.Iso7816.CommandApdu.set_Le(Int32 value)
如果 = 0x00
被删除,则命令被发送,但现在它在传输时挂起,这很奇怪,因为不应该有 return 数据。
ReaderPresent: catch case3
PCSC.Exceptions.InsufficientBufferException: The data buffer to receive returned data is too small for the returned data."
Case4Short(命令数据。预期响应数据)
Send: 80 11 00 00 04
Resp: 01 02 03 04 90 00
这是我的代码:
private bool SendApduCase4()
{
var success = false;
DebugWriteLine("case4 start");
using (var isoReader = new IsoReader(td.context, td.name, SCardShareMode.Shared, SCardProtocol.T1, false))
{
DebugWriteLine("case4 command");
var commandApdu = new CommandApdu(IsoCase.Case3Short, isoReader.ActiveProtocol)
{
CLA = 0x00,
INS = 0xA4,
P1 = 0x00,
P2 = 0x00,
Data = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
Le = 0x00
};
DebugWriteLine("case4 transmit");
var response = isoReader.Transmit(commandApdu);
if (response.HasData) DebugWriteLine(response.GetData().ToString());
if ((response.SW1 == 0x90) && (response.SW2 == 0x00))
{
if (response.HasData)
{
byte[] expected = new byte[] { 0x51, 0x01, 0x02, 0x03 };
if (response.GetData() == expected) success = true;
}
}
}
DebugWriteLine("case4 " + success.ToString());
return (success);
}
...类似地,它捕捉到命令并且从未将其发送到传输
我做错了什么?
哦,我在搜索中找到的最接近的答案是 ,但没有涵盖我需要的内容。
案例 3 不需要任何 return 数据。如果您不需要数据,则 Le
不应存在。 Le
是预期数据量的编码,称为Ne
。 Le = 00
的意思是:在 return 中给我一个 maximum 的 256 字节数:Ne = 256
。因此,包含任何 Le
值都会使其成为 ISO case 4 命令。如果 Le
不存在,则 Ne = 0
.
即使设置了Le
,智能卡通常仍会发送正确的响应。不幸的是,PCSC-sharp 库做出了不同的决定并不允许您发送命令 - 这可能是一件好事,因为智能卡实现 可能 仍然 return 一个错误。
当您删除 Le = 00
时,您 运行 进入了另一个问题。 SELECT 按名称(INS = A4
和 P1 = 04
与 P2 = 00
实际上可能 return 文件控制数据,使其成为 ISO case 4 命令。这次命令是正确的构造为 ISO 案例 3,但卡 returned 数据,在库中没有为其保留缓冲区 space - 在收到响应后给你一个错误。
要测试用例 3,您需要使用 INS = A4
、P1 = 04
和 P2 = 0C
,这表明不需要响应数据。或者任何其他实际的 ISO case 3 命令,例如 SELECT by File ID,当然。
备注:
- 这里的 ISO 是 ISO/IEC 7816-4 的缩写,如果摄影师可以滥用 ISO 名称那么智能卡开发者也可以
我正在开发 C# Java 卡(智能卡)程序,我正在尝试在 github.
上使用 PCSC-sharp 库这是我请求的 "short / tl;dr" 版本: PCSC-sharp 示例涵盖了 Iso7816 Case2Short。有人可以更正我下面的示例,或者提供一个 Iso7816 Case3Short(命令数据。无响应数据)和 Case4Short(命令数据。预期响应数据)的示例吗?
这是我请求的 "long" 版本: 在 Java 卡上,我同时使用标准和自定义 APDU 命令,并且我可以使用 python 脚本(使用智能卡库)成功调用这些命令。换句话说,我已经证明可以使用 Java 卡片命令。
我现在的目标是使用 PCSC-sharp 执行相同的命令,但是当我包含数据时我失败了(即 APDU LC > 0)。
这是 github 上的示例。请注意,我可以在仅更改 reader 名称、指令(select 文件而不是获取挑战)和 Le.
的情况下使用它var contextFactory = ContextFactory.Instance;
using (var ctx = contextFactory.Establish(SCardScope.System)) {
using (var isoReader = new IsoReader(ctx, "ACME Smartcard reader",
SCardShareMode.Shared, SCardProtocol.Any, false)) {
var apdu = new CommandApdu(IsoCase.Case2Short, isoReader.ActiveProtocol) {
CLA = 0x00, // Class
Instruction = InstructionCode.GetChallenge,
P1 = 0x00, // Parameter 1
P2 = 0x00, // Parameter 2
Le = 0x08 // Expected length of the returned data
};
var response = isoReader.Transmit(apdu);
Console.WriteLine("SW1 SW2 = {0:X2} {1:X2}", response.SW1, response.SW2);
// ..
}
}
我的示例版本中的 APDU 转换为:
Send: 00 A4 00 00 00 00
Resp: 90 00
...这对我有用并且适用于 Case2Short(无数据,无响应)
我要重新创建的是两种不同类型的传输:
Case3Short(命令数据。无响应数据)
Send: 00 A4 04 00 06 01 02 03 04 05 06 00
Resp 90 00
这是我的代码:
private bool SendApduCase3()
{
var success = false;
DebugWriteLine("case3 start");
using (var isoReader = new IsoReader(td.context, td.name, SCardShareMode.Shared, SCardProtocol.T1, false))
{
DebugWriteLine("case3 command");
var commandApdu = new CommandApdu(IsoCase.Case3Short, isoReader.ActiveProtocol)
{
CLA = 0x00,
INS = 0xA4,
P1 = 0x04,
P2 = 0x00,
Data = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
Le = 0x00
};
DebugWriteLine("case3 transmit");
var response = isoReader.Transmit(commandApdu);
if ((response.SW1 == 0x90) && (response.SW2 == 0x00)) success = true;
}
DebugWriteLine("case3 " + success.ToString());
return (success);
}
...但它捕捉到命令并且从未将其发送到传输,而是 return 出现以下错误:
System.ArgumentException:
Iso7816-4 Case3Short does not expect any data fields in its return value and therefore has no bytes for Le
at PCSC.Iso7816.CommandApdu.set_Le(Int32 value)
如果 = 0x00
被删除,则命令被发送,但现在它在传输时挂起,这很奇怪,因为不应该有 return 数据。
ReaderPresent: catch case3
PCSC.Exceptions.InsufficientBufferException: The data buffer to receive returned data is too small for the returned data."
Case4Short(命令数据。预期响应数据)
Send: 80 11 00 00 04
Resp: 01 02 03 04 90 00
这是我的代码:
private bool SendApduCase4()
{
var success = false;
DebugWriteLine("case4 start");
using (var isoReader = new IsoReader(td.context, td.name, SCardShareMode.Shared, SCardProtocol.T1, false))
{
DebugWriteLine("case4 command");
var commandApdu = new CommandApdu(IsoCase.Case3Short, isoReader.ActiveProtocol)
{
CLA = 0x00,
INS = 0xA4,
P1 = 0x00,
P2 = 0x00,
Data = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 },
Le = 0x00
};
DebugWriteLine("case4 transmit");
var response = isoReader.Transmit(commandApdu);
if (response.HasData) DebugWriteLine(response.GetData().ToString());
if ((response.SW1 == 0x90) && (response.SW2 == 0x00))
{
if (response.HasData)
{
byte[] expected = new byte[] { 0x51, 0x01, 0x02, 0x03 };
if (response.GetData() == expected) success = true;
}
}
}
DebugWriteLine("case4 " + success.ToString());
return (success);
}
...类似地,它捕捉到命令并且从未将其发送到传输
我做错了什么?
哦,我在搜索中找到的最接近的答案是
案例 3 不需要任何 return 数据。如果您不需要数据,则 Le
不应存在。 Le
是预期数据量的编码,称为Ne
。 Le = 00
的意思是:在 return 中给我一个 maximum 的 256 字节数:Ne = 256
。因此,包含任何 Le
值都会使其成为 ISO case 4 命令。如果 Le
不存在,则 Ne = 0
.
即使设置了Le
,智能卡通常仍会发送正确的响应。不幸的是,PCSC-sharp 库做出了不同的决定并不允许您发送命令 - 这可能是一件好事,因为智能卡实现 可能 仍然 return 一个错误。
当您删除 Le = 00
时,您 运行 进入了另一个问题。 SELECT 按名称(INS = A4
和 P1 = 04
与 P2 = 00
实际上可能 return 文件控制数据,使其成为 ISO case 4 命令。这次命令是正确的构造为 ISO 案例 3,但卡 returned 数据,在库中没有为其保留缓冲区 space - 在收到响应后给你一个错误。
要测试用例 3,您需要使用 INS = A4
、P1 = 04
和 P2 = 0C
,这表明不需要响应数据。或者任何其他实际的 ISO case 3 命令,例如 SELECT by File ID,当然。
备注:
- 这里的 ISO 是 ISO/IEC 7816-4 的缩写,如果摄影师可以滥用 ISO 名称那么智能卡开发者也可以