AES CMAC 计算 - 主机密码的输出长度不正确
AES CMAC calculation - output length for host cryptogram incorrect length
我有下面的函数,它应该 return 基于派生数据长度的 8 字节主机密码 "L" 但我得到的是 16 字节数据。虽然密钥是 128 位,但我期望 BC AESCMAC 函数将 return 数据基于派生数据中的 L 值。如果不是这种情况,我是否需要从输出中提取 MS 8 字节。以下是我的功能 -
private String scp03CalculatehostCryptogram(byte[] derivedSMACSessionKey, String hostChallenge, String cardChallenge) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, UnsupportedEncodingException {
// Reference : GPC_2.2_D_SCP03_v1.1.1 > 6.2.2.3 Host Authentication Cryptogram - The host cryptogram (8 bytes) is calculated using the data derivation scheme defined in section 4.1.5 with the session key S-MAC and the derivation constant set to “host authentication cryptogram generation”. The length of the cryptogram shall be reflected in the parameter “L” (i.e. '0040'). The “context” parameter shall be set to the concatenation of the host challenge (8 bytes) and the card challenge (8 bytes).
String labelForSMAC = "000000000000000000000001";
String separationIndicator = "00";
String lInteger = "0040";
String counter = "01";
String context = hostChallenge.concat(cardChallenge);
String hostCryptogramDerivationData = labelForSMAC.concat(separationIndicator).concat(lInteger).concat(counter).concat(context);
byte[] hostCryptogramDerivationDataBytes = DatatypeConverter.parseHexBinary(hostCryptogramDerivationData);
System.out.println(" Host Cryptogram Derivation data : "+DatatypeConverter.printHexBinary(hostCryptogramDerivationDataBytes));
Mac aescmac = Mac.getInstance("AESCMAC", "BC");
SecretKey scpENCKeyObject = new SecretKeySpec(derivedSMACSessionKey, "AES");
aescmac.init(scpENCKeyObject);
aescmac.update(hostCryptogramDerivationDataBytes);
byte[] hostCryptogram = aescmac.doFinal();
System.out.println(" Calculated Host Cryptogram : "+DatatypeConverter.printHexBinary(hostCryptogram));
return DatatypeConverter.printHexBinary(hostCryptogram);
}
输出:
主机密码推导数据:0000000000000000000000010000400161BD435249EC20B7AA984A2D47AD4302
计算的主机密码:6F405B9FD1438A4633A4289B618A1FB5
示例 - 派生的 smac 会话密钥:47297387E512687FBEB37D1C1F4B8F4C
我做错了什么?
长度L包含在密码的输入中,以使密码的输出尽可能具体。
显然 MAC 算法不会对输入给予任何尊重。 MAC 只需输入一个键,然后生成预定义数量的数据。 您的函数 应该创建密码。该密码需要输出数据 L 的大小作为参数。因此,如果您没有生成所需数量的输出数据,那么由您决定。
是的,一般来说,如果需要调整 PRF 的输出(例如您的函数)的大小,那么将采用最左边的字节。
我有下面的函数,它应该 return 基于派生数据长度的 8 字节主机密码 "L" 但我得到的是 16 字节数据。虽然密钥是 128 位,但我期望 BC AESCMAC 函数将 return 数据基于派生数据中的 L 值。如果不是这种情况,我是否需要从输出中提取 MS 8 字节。以下是我的功能 -
private String scp03CalculatehostCryptogram(byte[] derivedSMACSessionKey, String hostChallenge, String cardChallenge) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchProviderException, UnsupportedEncodingException {
// Reference : GPC_2.2_D_SCP03_v1.1.1 > 6.2.2.3 Host Authentication Cryptogram - The host cryptogram (8 bytes) is calculated using the data derivation scheme defined in section 4.1.5 with the session key S-MAC and the derivation constant set to “host authentication cryptogram generation”. The length of the cryptogram shall be reflected in the parameter “L” (i.e. '0040'). The “context” parameter shall be set to the concatenation of the host challenge (8 bytes) and the card challenge (8 bytes).
String labelForSMAC = "000000000000000000000001";
String separationIndicator = "00";
String lInteger = "0040";
String counter = "01";
String context = hostChallenge.concat(cardChallenge);
String hostCryptogramDerivationData = labelForSMAC.concat(separationIndicator).concat(lInteger).concat(counter).concat(context);
byte[] hostCryptogramDerivationDataBytes = DatatypeConverter.parseHexBinary(hostCryptogramDerivationData);
System.out.println(" Host Cryptogram Derivation data : "+DatatypeConverter.printHexBinary(hostCryptogramDerivationDataBytes));
Mac aescmac = Mac.getInstance("AESCMAC", "BC");
SecretKey scpENCKeyObject = new SecretKeySpec(derivedSMACSessionKey, "AES");
aescmac.init(scpENCKeyObject);
aescmac.update(hostCryptogramDerivationDataBytes);
byte[] hostCryptogram = aescmac.doFinal();
System.out.println(" Calculated Host Cryptogram : "+DatatypeConverter.printHexBinary(hostCryptogram));
return DatatypeConverter.printHexBinary(hostCryptogram);
}
输出:
主机密码推导数据:0000000000000000000000010000400161BD435249EC20B7AA984A2D47AD4302
计算的主机密码:6F405B9FD1438A4633A4289B618A1FB5
示例 - 派生的 smac 会话密钥:47297387E512687FBEB37D1C1F4B8F4C
我做错了什么?
长度L包含在密码的输入中,以使密码的输出尽可能具体。
显然 MAC 算法不会对输入给予任何尊重。 MAC 只需输入一个键,然后生成预定义数量的数据。 您的函数 应该创建密码。该密码需要输出数据 L 的大小作为参数。因此,如果您没有生成所需数量的输出数据,那么由您决定。
是的,一般来说,如果需要调整 PRF 的输出(例如您的函数)的大小,那么将采用最左边的字节。