gpt4 book ai didi

java - NIST SP 800-56A 级联/单步 key 推导函数的现有实现?

转载 作者:IT老高 更新时间:2023-10-28 23:18:28 25 4
gpt4 key购买 nike

关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。












想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。

2年前关闭。



Improve this question




有谁知道 NIST SP 800-56A 连接 key 派生函数/CONCAT KDF(最好是 Java)的任何现有实现?

NIST 出版物的第 5.8.1 节记录了 key 推导函数:使用离散对数加密的成对 key 建立方案的建议

链接在这里:http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf

微软的 CNG 有一个实现 here但是,如果将 Microsoft 实现的功能与 NIST SP 800-56A 中记录的参数进行比较,则它们不匹配,并且 Microsoft 的实现无法使用。我也尝试在 C++ 中实现一个示例程序,但我无法匹配参数。

有没有人能够尝试实现它或知道任何现有的实现?

我正在寻找一种能够证明为什么它符合 NIST 规范的实现。我已经看到了一些实现,我觉得它们不符合 NIST 规范(缺少参数、无效逻辑流等)。

如果你可以自己实现它,我总是很高兴分享我自己的源代码以供讨论。谢谢!这将是对开源社区的一个很好的贡献!

编辑:

感谢@Rasmus Faber,我终于可以结束这个问题,并希望回答其他人和我一样的问题。

这是我根据@Rasmus Faber 和我的原始代码编辑的代码:

ConcatKeyDerivationFunction.java

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
*
* Implementation of Concatenation Key Derivation Function<br/>
* http://csrc.nist.gov/publications/nistpubs/800-56A/SP800-56A_Revision1_Mar08-2007.pdf
*
*/

public class ConcatKeyDerivationFunction {

private static final long MAX_HASH_INPUTLEN = Long.MAX_VALUE;
private static final long UNSIGNED_INT_MAX_VALUE = 4294967295L;
private static MessageDigest md;

public ConcatKeyDerivationFunction(String hashAlg) throws NoSuchAlgorithmException {
md = MessageDigest.getInstance(hashAlg);
}

public byte[] concatKDF(byte[] z, int keyDataLen, byte[] algorithmID, byte[] partyUInfo, byte[] partyVInfo, byte[] suppPubInfo, byte[] suppPrivInfo) {
int hashLen = md.getDigestLength() * 8;

if (keyDataLen % 8 != 0) {
throw new IllegalArgumentException("keydatalen should be a multiple of 8");
}

if (keyDataLen > (long) hashLen * UNSIGNED_INT_MAX_VALUE) {
throw new IllegalArgumentException("keydatalen is too large");
}

if (algorithmID == null || partyUInfo == null || partyVInfo == null) {
throw new NullPointerException("Required parameter is null");
}

ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(algorithmID);
baos.write(partyUInfo);
baos.write(partyVInfo);
if (suppPubInfo != null) {
baos.write(suppPubInfo);
}
if (suppPrivInfo != null) {
baos.write(suppPrivInfo);
}
} catch (IOException e) {
throw new RuntimeException(e);
}

byte[] otherInfo = baos.toByteArray();
return concatKDF(z, keyDataLen, otherInfo);
}

private byte[] concatKDF(byte[] z, int keyDataLen, byte[] otherInfo) {
keyDataLen = keyDataLen / 8;
byte[] key = new byte[keyDataLen];

int hashLen = md.getDigestLength();
int reps = keyDataLen / hashLen;

if (reps > UNSIGNED_INT_MAX_VALUE) {
throw new IllegalArgumentException("Key derivation failed");
}

int counter = 1;
byte[] counterInBytes = intToFourBytes(counter);

if ((counterInBytes.length + z.length + otherInfo.length) * 8 > MAX_HASH_INPUTLEN) {
throw new IllegalArgumentException("Key derivation failed");
}

for (int i = 0; i <= reps; i++) {
md.reset();
md.update(intToFourBytes(i + 1));
md.update(z);
md.update(otherInfo);

byte[] hash = md.digest();
if (i < reps) {
System.arraycopy(hash, 0, key, hashLen * i, hashLen);
} else {
System.arraycopy(hash, 0, key, hashLen * i, keyDataLen % hashLen);
}
}
return key;
}

private byte[] intToFourBytes(int i) {
byte[] res = new byte[4];
res[0] = (byte) (i >>> 24);
res[1] = (byte) ((i >>> 16) & 0xFF);
res[2] = (byte) ((i >>> 8) & 0xFF);
res[3] = (byte) (i & 0xFF);
return res;
}
}

@Rasmus Faber:感谢您的努力。我给你上面的代码完全信任。我对上面的代码所做的是添加代码以按照 NIST 规范的要求执行验证。

此外,我修复了一个错误,其中传入的 keyDataLen 旨在指定以位为单位的长度,但它被视为以字节为单位的长度。因此,生成的 key 最终大了 8 倍。

这是通过添加一行来修复的 keyDataLen = keyDataLen/8;在第二种方法的第一行。

感谢大家的支持,希望这段代码对开源社区大有帮助!

最佳答案

这是一个快速而肮脏的实现:

    public byte[] concatKDF(String hashAlg, byte[] z, int keyDataLen, byte[] algorithmID, byte[] partyUInfo, byte[] partyVInfo, byte[] suppPubInfo, byte[] suppPrivInfo) throws NoSuchAlgorithmException
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
baos.write(algorithmID);
baos.write(partyUInfo);
baos.write(partyVInfo);
baos.write(suppPubInfo);
baos.write(suppPrivInfo);
} catch (IOException e) {
throw new RuntimeException(e);
}

byte[] otherInfo = baos.toByteArray();
return concatKDF(hashAlg, z, keyDataLen, otherInfo);
}

public byte[] concatKDF(String hashAlg, byte[] z, int keyDataLen, byte[] otherInfo) throws NoSuchAlgorithmException
{
byte[] key = new byte[keyDataLen];
MessageDigest md = MessageDigest.getInstance(hashAlg);
int hashLen = md.getDigestLength();
int reps = keyDataLen / hashLen;
for(int i=1;i<=reps;i++){
md.reset();
md.update(intToFourBytes(i));
md.update(z);
md.update(otherInfo);
byte[] hash = md.digest();
if(i<reps){
System.arraycopy(hash, 0, key, hashLen*(i-1), hashLen);
}else{
if(keyDataLen % hashLen == 0){
System.arraycopy(hash, 0, key, hashLen*(i-1), hashLen);
}else{
System.arraycopy(hash, 0, key, hashLen*(i-1), keyDataLen % hashLen);
}
}
}
return key;
}

public byte[] intToFourBytes(int i){
byte[] res = new byte[4];
res[0] = (byte) (i >>> 24);
res[1] = (byte) ((i >>> 16) & 0xFF);
res[2] = (byte) ((i >>> 8) & 0xFF);
res[3] = (byte) (i & 0xFF);
return res;
}

关于java - NIST SP 800-56A 级联/单步 key 推导函数的现有实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10879658/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com