Curve25519公钥是309字节,私钥是587,不应该是32字节吗?

1 java bouncycastle diffie-hellman public-key

我正在尝试使用 bouncycastle 在我的 java 程序中实现 curve25519,这是我想出的代码:

package crypto;

import org.bouncycastle.asn1.x9.X9ECParameters;
import org.bouncycastle.crypto.ec.CustomNamedCurves;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.security.*;

public class Curve {

    public KeyPair generateKeyPair() throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        X9ECParameters ecP = CustomNamedCurves.getByName("curve25519");
        ECParameterSpec ecSpec = new ECParameterSpec(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
        keyGen.initialize(ecSpec);
        return keyGen.generateKeyPair();
    }

}
Run Code Online (Sandbox Code Playgroud)

而我的主要方法:

package crypto;

import java.nio.charset.StandardCharsets;
import java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

public class Test_Curve {

    public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
        Curve curve = new Curve();
        KeyPair keys = curve.generateKeyPair();
        System.out.println(keys.getPrivate().getEncoded().length);
        System.out.println(keys.getPublic().getEncoded().length);
        System.out.println(new String(Base64.getEncoder().encode(keys.getPrivate().getEncoded()), StandardCharsets.US_ASCII));
        System.out.println(new String(Base64.getEncoder().encode(keys.getPublic().getEncoded()), StandardCharsets.US_ASCII));
    }

}
Run Code Online (Sandbox Code Playgroud)

这是我从程序中得到的输出:

587
309
MIICRwIBADCB6gYHKoZIzj0CATCB3gIBATArBgcqhkjOPQEBAiB/////////////////////////////////////////7TBEBCAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqYSRShRAQge0Je0Je0Je0Je0Je0Je0Je0Je0Je0Je0JgtenHcQyGQEQQQqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0kWiCuGaG4oIa04B7dLHdI0UySPU1+bXxhsinpxaJ+ztPZAiAQAAAAAAAAAAAAAAAAAAAAFN753qL3nNZYEmMaXPXT7QIBCASCAVMwggFPAgEBBCALaQ79+nbqlaXL3aLfYSIMRPzMgKxdayqZA7WQ20XhhaCB4TCB3gIBATArBgcqhkjOPQEBAiB/////////////////////////////////////////7TBEBCAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqYSRShRAQge0Je0Je0Je0Je0Je0Je0Je0Je0Je0Je0JgtenHcQyGQEQQQqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0kWiCuGaG4oIa04B7dLHdI0UySPU1+bXxhsinpxaJ+ztPZAiAQAAAAAAAAAAAAAAAAAAAAFN753qL3nNZYEmMaXPXT7QIBCKFEA0IABCsAt6tKs2ZiLn85ggNCjdx++vGIwNOI0X0OsXscSMgOBzCpMDGDOdt1ejV5LiPqorjd6fIIZG4PWCXjvjxCO+M=
MIIBMTCB6gYHKoZIzj0CATCB3gIBATArBgcqhkjOPQEBAiB/////////////////////////////////////////7TBEBCAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqYSRShRAQge0Je0Je0Je0Je0Je0Je0Je0Je0Je0Je0JgtenHcQyGQEQQQqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0kWiCuGaG4oIa04B7dLHdI0UySPU1+bXxhsinpxaJ+ztPZAiAQAAAAAAAAAAAAAAAAAAAAFN753qL3nNZYEmMaXPXT7QIBCANCAAQrALerSrNmYi5/OYIDQo3cfvrxiMDTiNF9DrF7HEjIDgcwqTAxgznbdXo1eS4j6qK43enyCGRuD1gl4748Qjvj
Run Code Online (Sandbox Code Playgroud)

但是,这对我来说似乎不正确。我读到 curve25519 公钥应该是 32 个字节,而这显然不是。我已经完成了尽职调查并从谷歌中提取了几个示例并进行了尝试,但仍然遇到了同样的问题。任何帮助是极大的赞赏。

dav*_*085 5

Curve25519 不是 X9/Weierstrass 曲线。您所做的将与其他实现不兼容,这些实现都使用 Bernstein 的规范,用于称为 X25519 的 X-only Montgomery-form Diffie-Hellman 或称为 Ed25519 的 Edwards-form 签名(通常没有预散列)。Java 用于所有非对称密钥(公共和私有)的密钥编码绝不仅仅是密钥本身,而是包含元数据的通用编码,X.509 SPKI 或 PKCS8并通过强制此曲线首先为 Weierstrass 形式(对于 X9)然后通过使用显式和长期过时的 X9 形式将元数据极大地膨胀到未命名的形式ECParameterSpec

而是分别在两者和后续or 中使用算法 "X25519"or 。标准编码仍然比原始密钥长,但要少得多。为了获得原始密钥,在 Oracle/Open 中适当地使用由算法相关的实现(提供者)类实现的接口。(编辑)在足够新的 Java 上运行的最近有弹性(1.65 up)也这样做;否则 AFAICS 你必须获得通用 (ASN.1) 编码并解析它——Bouncy 确实单独公开了 (ASN.1) 功能(通过它的“轻量级”API 而不是 JCA)(并且从那时起大致如此)。"ED25519"KeyPairGeneratorKeyAgreementSignature{XEC,EdEC}{Public,Private}Key