Authentication SAM读卡器加密主机身份验证
我们目前正在使用基于操作模式ISO/IEC 7816模式和OMNIKEY的ICC protocoll T1的DESFire SAM读卡器。我们使用PCSC和PCSC.7816 nuget软件包进行c#程序,以便成功验证SAM卡的运行。我们发现需要某种主机身份验证,以便使SAM卡的会话为进一步通信做好准备。根据DESFire SAM protocoll规范,需要两个步骤:第一个是此命令: CLA INS P1 P2 LC数据LE 0x80 0xA4身份验证模式0x00 0x02密钥号| |密钥V 0x00 在c#代码中,它是这样实现的,使用正确的返回码并生成8字节加密的随机编号:Authentication SAM读卡器加密主机身份验证,authentication,encryption,smartcard,des,sam,Authentication,Encryption,Smartcard,Des,Sam,我们目前正在使用基于操作模式ISO/IEC 7816模式和OMNIKEY的ICC protocoll T1的DESFire SAM读卡器。我们使用PCSC和PCSC.7816 nuget软件包进行c#程序,以便成功验证SAM卡的运行。我们发现需要某种主机身份验证,以便使SAM卡的会话为进一步通信做好准备。根据DESFire SAM protocoll规范,需要两个步骤:第一个是此命令: CLA INS P1 P2 LC数据LE 0x80 0xA4身份验证模式0x00 0x02密钥号| |密钥V
var contextFactory = ContextFactory.Instance;
byte[] data = null;
using (var ctx = contextFactory.Establish(SCardScope.System))
{
// share mode shared
using (var isoReader = new IsoReader(ctx, "HID Global OMNIKEY 3x21 Smart Card Reader 0",
SCardShareMode.Shared, SCardProtocol.Any, false))
{
var keyBytes = new byte[] { 0x00, 0x00 }; // key no and key version of master key
var apdu = new CommandApdu(IsoCase.Case4Short, isoReader.ActiveProtocol)
{
CLA = 0x80, // Class
INS = 164, // instruction hex 0xA4,
P1 = 0x00, // Auth Mode 0 select application
P2 = 0x00, // Parameter 2
Le = 0x00,
// Expected length of the returned data
Data = keyBytes
};
var response = isoReader.Transmit(apdu);
if (response.SW1 == 144 && response.SW2 == 175)
{
data = response.GetData();
Console.WriteLine("Successfully read enc(rndB)");
}
}
}
return data;
根据功能描述,下一步是以下命令:
CLA INS P1 P2 LC数据LE
0x80 0xA4 0x00 0x00 0x10 ekNo(RndA+RndB')0x00
我现在的问题是如何检索RndA并像输入数据ekNo(RndA+RndB')中描述的那样对其进行加密。文件上写着“加密(随机数A | |随机数B,旋转1
字节)”
我们是否需要公钥并根据SAM卡上使用的算法对其进行加密?
因为我们还有一个来自另一个智能卡api示例的代码示例,用于使用DESFire卡,并且验证步骤是基于选择应用程序和使用16字节长的密钥完成的
#region Assembly CardModule.DESFIRE,
// SmartCard-API-SDK-trial-v5.0.20.304\smartcard-api-sdk-trial\DESFire\lib\CardModule.DESFIRE.dll
#endregion
using Subsembly.SmartCard;
namespace SmartCardAPI.CardModule.DESFIRE
{
public class DESFireCardEdge
{
public DESFireCardEdge(CardHandle hCard, bool pcsc2enabled = true);
~DESFireCardEdge();
public byte[] UID { get; }
public bool Authenticate(int cardKeyNumber, byte[] authenticationKey);
public bool AuthenticateAES(int cardKeyNumber, byte[] authenticationKey);
public bool SelectApplication(int aid);
}
下面是尝试生成自己的随机数以实现主机身份验证的代码示例第二步:
rndABytes = new byte[8];
for (int i = 0; i < rndABytes.Length; i++)
{
rndABytes[i] = Convert.ToByte(new Random().Next(0, 255));
}
var bytes = rndB.ToList();
var byteArr = bytes.ToArray();
RotateLeft(byteArr);
var rndABytesList = rndABytes.ToList();
rndABytesList.AddRange(byteArr);
var apdu = new CommandApdu(IsoCase.Case4Short, isoReader.ActiveProtocol)
{
CLA = 0x80, // Class
INS = 164, //InstructionCode.GetChallenge,
P1 = 0x00, // Auth Mode 0 select application
P2 = 0x00, // Parameter 2
Le = 0x00,
// Expected length of the returned data
Data = rndABytesList.ToArray()
};
rndABytes=新字节[8];
for(int i=0;i
如果我们将随机数生成一个8字节长的数组,并对rndB号进行位移位,则命令将成功执行,但没有有效的身份验证