首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在X25519中为PrivateKey生成PublicKey?

如何在X25519中为PrivateKey生成PublicKey?
EN

Stack Overflow用户
提问于 2019-10-27 06:29:42
回答 1查看 168关注 0票数 0

目前,我正在使用基于X25519密钥的加密。

我的问题基本上是,如何从现有的X25519 PrivateKey派生PublicKey

我尝试过以下几种方法:

代码语言:javascript
复制
    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时,它们就不同了。

代码语言:javascript
复制
    public KeyPair generateX25519KeyPair() throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(X25519);
        return keyPairGenerator.generateKeyPair();
    }

我决定查阅KeyPairGenerator (XDHKeyPairGenerator实现)的源代码,并在他们进行乘法运算时找到部分:

代码语言:javascript
复制
    /**
     *
     * 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的方法使用另一个乘法:

代码语言:javascript
复制
    /**
     * 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()方法应用于结果:

代码语言:javascript
复制
     * 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派生时不应用这种编码。

EN

回答 1

Stack Overflow用户

发布于 2019-10-27 07:23:43

公钥是通过将基点乘以“钳制”的秘密标量并返回编码的X坐标来计算的。

钳位意味着屏蔽3个最低有效位,屏蔽最高位,并设置第二个最高位。

详情请参见RFC7748

但看起来这更像是一个编程问题,而实际问题可能与X25519无关。对于给定的密码,将从该代码获得的输出与使用不同库实现的相同操作进行比较。如果公钥匹配,则问题出在其他地方。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58649797

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档