在JavaCard上更改GP-Key

时间:2015-12-08 12:56:00

标签: javacard globalplatform

我想阻止我的卡片 进一步发展。 有谁知道怎么做 用GPShell? 我找到了这个命令:

open_sc -security 3 -keyind 0 -keyver 0 -key "currentKey" -keyDerivation visa2 // Open secure channel
put_sc_key -keyver 0 -newkeyver 0 -mac_key "newKey" -enc_key "newKey" -kek_key "newKey"-current_kek "currentKey"

但得到了这个错误:

put_secure_channel_keys() returns 0x80206A80 (6A80: Wrong data / Incorrect values in command data.)

我也尝试过:

put_sc_key -keyver 1 -newkeyver 1 -key "newKey" -keyDerivation visa2

但得到了这个错误:

put_secure_channel_keys() returns 0x80206A88 (6A88: Referenced data not found.)

1 个答案:

答案 0 :(得分:0)

两年前我用GPShell和金雅拓卡处理同样的问题(不太确定我是否得到0x6A80,但可能是的) - 如果我没记错的话,GPShell使用了错误的多样化数据来获取新密钥和(更糟糕的是,使用put_sc_key选项的-keyDerivation命令的KEK错误。

也许这已在上游修复 - 您可能需要考虑尝试最新的svn版本(更新:I was told that the problem is fixed now)。

那次我对svn版本419使用了以下丑陋的修改:

--- globalplatform/src/globalplatform.c (revision 419)
+++ globalplatform/src/globalplatform.c (working copy)
@@ -61,6 +61,10 @@
 #ifndef MAX_PATH
 #define MAX_PATH 257
 #endif
+
+static BYTE savedKEK[16];
+
+

 static BYTE C_MACDerivationConstant[2] = {0x01, 0x01}; //!< Constant for C-MAC session key calculation.
 static BYTE ENCDerivationConstant[2] = {0x01, 0x82};//!< Constant for encryption session key calculation.
@@ -3309,6 +3313,15 @@
        OPGP_LOG_START(_T("VISA2_derive_keys"));

        OPGP_LOG_HEX(_T("VISA2_derive_keys: Base Key Diversification Data: "), baseKeyDiversificationData, 10);
+       static BYTE savedBaseKeyDiversificationData[10];
+       if(memcmp(baseKeyDiversificationData, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10)==0) {
+           // In trouble -> patch
+           memcpy(baseKeyDiversificationData, savedBaseKeyDiversificationData, 10);
+       } else {
+           memcpy(savedBaseKeyDiversificationData, baseKeyDiversificationData, 10);
+       }
+
+       OPGP_LOG_HEX(_T("VISA2_derive_keys: Base Key Diversification Data2: "), baseKeyDiversificationData, 10);

        /* Key Diversification data VISA 2
        KDCAUTH/ENC xxh xxh || IC serial number || F0h 01h ||xxh xxh || IC serial number
@@ -3971,6 +3984,9 @@

        OPGP_LOG_MSG(_T("mutual_authentication: S-MAC Session Key: "), secInfo->C_MACSessionKey, 16);

+       if (secInfo->secureChannelProtocol == GP211_SCP01) {
+               memcpy(savedKEK, secInfo->dataEncryptionSessionKey, 16);
+       }
 #ifdef OPGP_DEBUG
        if (secInfo->secureChannelProtocol == GP211_SCP01) {
                OPGP_LOG_HEX(_T("mutual_authentication: Data Encryption Key: "), secInfo->dataEncryptionSessionKey, 16);
@@ -4513,6 +4529,12 @@
        OPGP_ERROR_STATUS status;
        GP211_SECURITY_INFO gp211secInfo;
        mapOP201ToGP211SecurityInfo(*secInfo, &gp211secInfo);
+
+       if(memcmp(KEK, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", 10)==0) {
+           // In trouble -> patch
+           memcpy(KEK, savedKEK, 16);
+       }
+
        memcpy(gp211secInfo.dataEncryptionSessionKey, KEK, 16);
        status = put_secure_channel_keys(cardContext, cardInfo, &gp211secInfo, keySetVersion, newKeySetVersion,
                NULL, new_encKey, new_macKey, new_KEK);

这个脚本对我有用:

mode_201
....skipped...
open_sc -security 3 -keyind 0 -keyver 0 -key <motherKey> -keyDerivation visa2
put_sc_key -scp 1 -keyver 1 -newkeyver 1 -key <newMotherKey> -keyDerivation visa2 -current_kek 00000000000000000000000000000000

如果我的记忆很好,补丁会做以下事情:

  • 在首次身份验证期间保存关键多样化数据(即open_sc),然后在为put_sc_key多样化新密钥时使用它们。

  • 在第一次身份验证期间保存派生的KEK,然后将其用作KEK以进行新的密钥值加密(这通过使用0000....0000 KEK触发)。

您可以考虑使用其他工具(GlobalPlatformPro?),但我不确定它是否支持PUT KEY的密钥多样化(从未尝试过)。

祝你好运!

编辑&gt;关于阻止我的卡进一步开发部分

这种方法(可能)改变了ISD密钥,在大多数情况下(即没有其他SD到​​位时)保护对卡管理的访问

  • 我的赌注是你的卡最初有一个众所周知的javacard默认密钥 - 并且通过将这些默认密钥更改为其他值,可以防止攻击者知道这些默认密钥从身份验证到您的卡的密钥(强调强意味着您应该避免使用0102030405..等密钥

  • 更改密钥实际上并不会阻止实体知道新密钥管理卡内容 - 使用密钥可以随意管理卡。我们的想法是,您是唯一一个可以访问密钥的人

  • 如果你的applet使用它,更改(I)SD键会更改GPSystem.getSecureChannel()使用的密钥

唯一的方法(我知道)阻止卡进行进一步管理,同时保留加载的小程序功能是阻止(I)SD访问失败大约尝试认证约10次 - 因为大多数卡阻止访问在这种情况下(I)SD(您的里程可能会有所不同)。我不推荐这种方式。