在this question有关从欧洲DTCO公司卡读取数据的过程中,我获得了以下截图中的算法(来自this document附录11),但是我不清楚如何执行这两个突出显示的步骤.
>我看到Sign是包含证书的数组的一部分,但用公钥打开它意味着什么?我可以通过从卡中读取CA_Certificate并使用CAR发出管理安全环境APDU(参见算法的第一步)来成功执行该步骤.但是,通过这种方式选择了公钥,我在开放的Sign步骤中使用了哪些公钥. MSE选择一个,但我没有;我只有ERCA的欧洲公钥,但是我在卡中选择了相同的密钥吗?我没有任何私钥,但我需要它们.
>在检查哈希(C’)= H’的步骤中,我应该如何计算哈希值?进行加密/解密/散列似乎有很多不同的方式(格式正确吗?),我很困惑.
我真正需要能够读取我需要的数据是使用EXTERNAL AUTHENTICATE进行身份验证,紧接在返回8字节质询的GET CHALLENGE之后.我认为我需要用它来计算EXTERNAL AUTHENTICATE的密码.我在下面找到了示例代码(see full post),虽然它看起来像是某种类似C语言的脚本语言(我正在使用C#),但对于不同类型的智能卡,它似乎与我必须使用的非常类似.
// // Authenticate against CardOS card // var card = new Card(_scsh3.reader); var crypto = new Crypto(); var key = new Key(); key.setComponent(Key.DES,new ByteString("01010101010101010101010101010101",HEX)); // Get challenge var challenge = card.sendApdu(0x00,0x84,0x00,8,[0x9000]); // Crypto.DES_MAC_EMV is a CBC generated Retail-MAC var cipher = crypto.sign(key,Crypto.DES_MAC_EMV,challenge); card.sendApdu(0x00,0x82,0x81,cipher); print("Card returns " + card.SW.toString(16) + " - " + card.SWMSG);
差异是
>附加的P2参数表明已经完成了管理安全环境,可能是使用Card_Certificate的CAR’,虽然它与CA_Certificate的CAR’有关,但对我来说不起作用.
>示例代码中的Lc为0x80而不是0x81.
>我计算在这里使用的任何密码都必须是128个字节长,而不清楚样本中的密码长度.
解决方法
您的代码段通过对称密钥(也称为密钥)处理身份验证.假设这个秘密仅由授权人员知道.您认为是LC的0x81实际上是P2,意味着“请使用本地密钥#1”来验证使用此密钥的MAC计算.事实上,将8字节随机数作为用于计算(零售或任何)MAC的输入通常(即应用标准填充方案)导致16字节结果.顺便说一句,示例中的DES密钥非常糟糕.每个字节的最低有效位是奇偶校验位,因此密钥仅由零字节组成.
除了以某种方式进行身份验证之外,这两种方案都没有任何共同点.
有关详细信息,请参阅ISO 7816-8(用于执行安全操作),ISO 7816-4(用于外部验证,获取质询和大多数其他智能卡命令).如果不花钱,这些很难获得 – 旧版本可能会在www上找到 – 而且读起来很干,很难理解. Rankl / Effing“Handbuch der Chipkarten”中有更多解释,但有时会报道英文翻译“智能卡手册”是特殊的.对于证书材料,我建议使用Schneier,Applied Cryptography,它还有数百个参考资料.