【发布时间】:2019-10-26 22:29:41
【问题描述】:
我目前正在使用基于 X25519 密钥的加密。
我的问题是,基本上,如何从现有的 X25519 PrivateKey 派生 PublicKey?
我尝试了以下方法:
protected PublicKey generatePublicKeyFromPrivate(PrivateKey privateKey) throws GeneralSecurityException {
PublicKey basePublicKey = generatePublicKey(BigInteger.valueOf(9));
KeyAgreement keyAgreement = KeyAgreement.getInstance(X25519);
keyAgreement.init(privateKey, new ECGenParameterSpec(X25519));
keyAgreement.doPhase(basePublicKey, true);
byte[] bytes = keyAgreement.generateSecret();
return generatePublicKey(new BigInteger(bytes));
}
PublicKey 生成成功。我什至将这种方法与第三方库方法(Google Tink)进行了比较:生成的 PubliKeys 匹配。
但是,当我尝试使用 Java 的 KeyPairGenerator 同时获取 PrivateKey 和 PubliKey,然后尝试自己为该 PrivateKey 生成一个 PublicKey 时,它们会有所不同。
public KeyPair generateX25519KeyPair() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(X25519);
return keyPairGenerator.generateKeyPair();
}
我决定查找KeyPairGenerator(XDHKeyPairGenerator 实现)的源代码,并找到了它们进行乘法运算的部分:
/**
*
* Multiply an encoded scalar with a point as a BigInteger and return an
* encoded point. The array k holding the scalar will be pruned by
* modifying it in place.
*
* @param k an encoded scalar
* @param u the u-coordinate of a point as a BigInteger
* @return the encoded product
*/
public byte[] encodedPointMultiply(byte[] k, BigInteger u) {
pruneK(k);
ImmutableIntegerModuloP elemU = field.getElement(u);
return pointMultiply(k, elemU).asByteArray(params.getBytes());
}
但是,用于单独生成PubliKey的方法使用了另一种乘法:
/**
* Compute a public key from an encoded private key. This method will
* modify the supplied array in order to prune it.
*/
public BigInteger computePublic(byte[] k) {
pruneK(k);
return pointMultiply(k, this.basePoint).asBigInteger();
}
如您所见,不同之处在于,在第一种情况下,他们将asByteArray() 方法应用于结果:
* Returns the little-endian encoding of this' % 2^(8 * len), where this'
* is the canonical integer value equivalent to this.
*
* @param len the length of the desired array
* @return a byte array of length len containing the result
*/
default byte[] asByteArray(int len) {
byte[] result = new byte[len];
asByteArray(result);
return result;
}
所以我的问题是:他们为什么要这样做?为什么在使用KeyPairGenerator 时将这种“小端编码”应用于PublicKey,而当PublicKey 单独派生自PrivateKey 时则不应用。
【问题讨论】:
-
这确实是一个关于特定库的编程问题。 BouncyCastle 邮件列表 (bouncycastle.org/mailing_lists.html) 会是一个更好的提问场所。
标签: encryption