如何使用 javacardx.security.derivation 定义的 KDF (X9.63) 提取加密和 MAC 密钥
How to extract encryption and MAC keys using KDF (X9.63) defined by javacardx.security.derivation
根据Java Card v3.1 新包定义javacardx.security.derivation
KDF X9.63 适用于三个输入:输入密码、计数器和共享信息。
取决于生成密钥的长度material,对哈希进行多轮计算以生成最终输出。
我正在通过 JC 使用此 KDF API 为 16 字节加密密钥、16 字节 IV 生成 64 字节输出(由 2 轮 SHA-256 执行),和一个 32 字节-MAC Key.
注意:这只是伪代码,用于提出我的问题并提供必要的详细信息。
DerivationFunction df = DerivationFunction.getInstance(DerivationFunction.ALG_KDF_ANSI_X9_63, false);
df.init(KDFAnsiX963Spec(MessageDigest.ALG_SHA_256, input, sharedInfo, (short) 64);
SecretKey encKey = KeyBuilder.buildKey(KeyBuilder.TYPE_AES, (short)16, false);
SecretKey macKey = KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC, (short)32, false);
df.nextBytes(encKey);
df.nextBytes(IVBuffer, (short)0, (short)16);
df.lastBytes(macKey);
我有以下问题:
什么时候进行KDF?这些是在 df.init() 期间执行还是在 df.nextBytes()
& df.lastBytes()
期间执行?
一轮 KDF 将生成 32 字节输出(考虑 SHA-256 算法),那么 API 的 df.nextBytes()
和 df.lastBytes()
如何处理任何输出预期长度 < 32 字节?
在此 KDF 计数器在每个下一轮递增,那么如何在 df.nextBytes()
和 df.lastBytes()
API 之间管理计数器?
- When rounds of KDF are performed? Are these performed during df.init() or during
df.nextBytes()
& df.lastBytes()
?
这似乎是特定于我的实现。一次执行所有计算可能会更快,但在这种情况下,等待第一个字节请求仍然有意义。另一方面,RAM 通常也是一个问题,因此按需生成也有一定意义。不过,这需要稍微复杂一些的实现。
输出大小是预先指定的事实可能表明 API 设计者至少预见到一次生成所有密钥 material 的更简单方法(他们可能创建了一个在 JCF 对其进行同行评审之前实施。
- One KDF round will generate 32 bytes output (considering SHA-256 algorithm) then how API's
df.nextBytes()
& df.lastBytes()
will work with any output expected length < 32 bytes?
它通常会 return 最左边的字节(散列输出的)并且可能将其余字节留在缓冲区中。当 lastBytes
被调用时,这个缓冲区可能会与状态的其余部分一起被销毁(所以不要忘记这样做)。
请注意,API 明确指出,如果您想再次使用它,您必须重新初始化 DerivationFunction
实例。因此,这是一个非常强烈的迹象,表明他们虽然破坏了密钥 material(FIPS 和通用标准认证要求的东西,而不仅仅是常识)。
其他 KDF 的 可能 有不同的 returning 字节方式,但是使用最左边的字节然后在右边添加轮数是很常见的,你可以称之为普遍的。对于 ANSI X9.63 KDF,情况确实如此,并且在标准中明确指定了这种方式。
- In this KDF counter is incremented in every next round then how counter will be managed between
df.nextBytes()
& df.lastBytes()
API's?
这些是同一个class的方法,不能分开看,所以不是分开的API。 Class 个实例可以以任何他们想要的方式保持状态。它可能只是将计数器保存为 class 变量,但如果它决定在 init
或第一个 nextBytes
/ lastBytes
调用期间生成字节,那么甚至不需要计数器不再。
根据Java Card v3.1 新包定义javacardx.security.derivation
KDF X9.63 适用于三个输入:输入密码、计数器和共享信息。 取决于生成密钥的长度material,对哈希进行多轮计算以生成最终输出。
我正在通过 JC 使用此 KDF API 为 16 字节加密密钥、16 字节 IV 生成 64 字节输出(由 2 轮 SHA-256 执行),和一个 32 字节-MAC Key.
注意:这只是伪代码,用于提出我的问题并提供必要的详细信息。
DerivationFunction df = DerivationFunction.getInstance(DerivationFunction.ALG_KDF_ANSI_X9_63, false);
df.init(KDFAnsiX963Spec(MessageDigest.ALG_SHA_256, input, sharedInfo, (short) 64);
SecretKey encKey = KeyBuilder.buildKey(KeyBuilder.TYPE_AES, (short)16, false);
SecretKey macKey = KeyBuilder.buildKey(KeyBuilder.TYPE_HMAC, (short)32, false);
df.nextBytes(encKey);
df.nextBytes(IVBuffer, (short)0, (short)16);
df.lastBytes(macKey);
我有以下问题:
什么时候进行KDF?这些是在 df.init() 期间执行还是在
df.nextBytes()
&df.lastBytes()
期间执行?一轮 KDF 将生成 32 字节输出(考虑 SHA-256 算法),那么 API 的
df.nextBytes()
和df.lastBytes()
如何处理任何输出预期长度 < 32 字节?在此 KDF 计数器在每个下一轮递增,那么如何在
df.nextBytes()
和df.lastBytes()
API 之间管理计数器?
- When rounds of KDF are performed? Are these performed during df.init() or during
df.nextBytes()
&df.lastBytes()
?
这似乎是特定于我的实现。一次执行所有计算可能会更快,但在这种情况下,等待第一个字节请求仍然有意义。另一方面,RAM 通常也是一个问题,因此按需生成也有一定意义。不过,这需要稍微复杂一些的实现。
输出大小是预先指定的事实可能表明 API 设计者至少预见到一次生成所有密钥 material 的更简单方法(他们可能创建了一个在 JCF 对其进行同行评审之前实施。
- One KDF round will generate 32 bytes output (considering SHA-256 algorithm) then how API's
df.nextBytes()
&df.lastBytes()
will work with any output expected length < 32 bytes?
它通常会 return 最左边的字节(散列输出的)并且可能将其余字节留在缓冲区中。当 lastBytes
被调用时,这个缓冲区可能会与状态的其余部分一起被销毁(所以不要忘记这样做)。
请注意,API 明确指出,如果您想再次使用它,您必须重新初始化 DerivationFunction
实例。因此,这是一个非常强烈的迹象,表明他们虽然破坏了密钥 material(FIPS 和通用标准认证要求的东西,而不仅仅是常识)。
其他 KDF 的 可能 有不同的 returning 字节方式,但是使用最左边的字节然后在右边添加轮数是很常见的,你可以称之为普遍的。对于 ANSI X9.63 KDF,情况确实如此,并且在标准中明确指定了这种方式。
- In this KDF counter is incremented in every next round then how counter will be managed between
df.nextBytes()
&df.lastBytes()
API's?
这些是同一个class的方法,不能分开看,所以不是分开的API。 Class 个实例可以以任何他们想要的方式保持状态。它可能只是将计数器保存为 class 变量,但如果它决定在 init
或第一个 nextBytes
/ lastBytes
调用期间生成字节,那么甚至不需要计数器不再。