是否可以使用SHA3-512(Java9中可用的keccak的子集)在Java中生成密钥?
我搜索过很多噪音和文档,试图弄明白这一点。 目前似乎SHA3-512可用作MessageDigest的哈希,但不能用于生成密钥。我下面的代码试图以可预测的方式生成密钥(用于钱包目的,如BIP32,但超出货币到区块链使用)
public static String GenerateSeed() throws Exception {
SecureRandom random = new SecureRandom();
byte[] seed = random.generateSeed(512);
return Base64.getEncoder().encodeToString(seed);
}
public static Keyz GenerateKey(String seedString) {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
KeyPairGenerator keyGen1 = KeyPairGenerator.getInstance("ECDSA");
ECGenParameterSpec ecSpec = new ECGenParameterSpec("secp256k1");
SecureRandom random1 = SecureRandom.getInstance("SHA1PRNG");
random1.setSeed(Base64.getDecoder().decode(seedString));
keyGen1.initialize(ecSpec, random1);
KeyPair keyPair1 = keyGen1.generateKeyPair();
PublicKey pub1 = keyPair1.getPublic();
PrivateKey priv1 = keyPair1.getPrivate();
//Keyz is a simple model that stores the 3 fields below and overrides equals and hashcode on those fields
return new Keyz("random", pub1, priv1);
}
正如您所看到的,它使用SHA1PRNG可预测地确定性地生成密钥对(我对这方面的安全性问题很好),以便可以确定性地重新创建密钥。
这是一个JUnit测试,用于确保密钥是确定性的(适用于SHA1PRNG,需要在SHA3PRNG中工作)。理想情况下,需要的是GenerateSeed中的SHA3-512 TRNG和GenerateKey中的SHA3PRNG。由于密钥生成器需要SecureRandom,如果java.Security.SecureRandom仍然像SHA1PRNG那样不安全,我会感到惊讶。
@Test
public void shouldReturnDeterministicKeys() throws Exception {
String seedString = GenerateSeed();
Keyz random1 = GenerateKey(seedString);
Keyz random2 = GenerateKey(seedString);
//This assertion works as we override equals and hashcode
assertEquals(random1, random2);
}
有人可以告诉我他们是否想办法让这个工作
答案 0 :(得分:2)
看起来你想要的东西不是开箱即用的:
请注意,SHA1
和SHA1PRNG
不相同。虽然前者是散列算法,但后者是伪随机生成算法(当然,使用SHA1
来更新其内部状态。)这种差异的一个微不足道的结果是,SHA1
输出一个固定的位大小,SHA1PRNG
输出任意多个位。
由于存在这种差异,SHA3-512
不能直接用作PRNG
,尽管它在Java中可用。您需要做的是,使用PRNG
实现SHA3-512
算法(这部分非常棘手,因为生成伪随机流非常困难。)并通过自定义Security Provider
注册它(例如Bouncy Castle
),名称为MySHA3PRNG
。之后,您可以像MySHA3PRNG
一样获取名称为SHA1PRNG
的实例。其余的仍然是原样。
这个棘手部分的一个主要问题可能如下:引自here,
论文" Sponge-based pseudo-random number generators"谈到这一点,它还描述了一种干净有效的方法来构建具有(Keccak)海绵功能的重新种子
PRNG
。您将获得的是基于加密哈希函数的PRNG
......具有通常的安全隐患。例如:本文明确指出您应该定期重新定位并使用足够的熵来防止攻击者在
PRNG
期间(这可能是您已经听过的内容)倒退。
但是,您需要的是PRNG
算法,不需要重新播种。我希望您有足够的理论背景证明您的自定义PRNG
算法是安全的。