java - Curve25519 公钥是 309 字节,私钥是 587。不应该是 32 字节吗?
问题描述
我正在尝试使用 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();
}
}
我的主要方法:
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));
}
}
这是我从程序中得到的输出:
587
309
MIICRwIBADCB6gYHKoZIzj0CATCB3gIBATArBgcqhkjOPQEBAiB/////////////////////////////////////////7TBEBCAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqYSRShRAQge0Je0Je0Je0Je0Je0Je0Je0Je0Je0Je0JgtenHcQyGQEQQQqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0kWiCuGaG4oIa04B7dLHdI0UySPU1+bXxhsinpxaJ+ztPZAiAQAAAAAAAAAAAAAAAAAAAAFN753qL3nNZYEmMaXPXT7QIBCASCAVMwggFPAgEBBCALaQ79+nbqlaXL3aLfYSIMRPzMgKxdayqZA7WQ20XhhaCB4TCB3gIBATArBgcqhkjOPQEBAiB/////////////////////////////////////////7TBEBCAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqYSRShRAQge0Je0Je0Je0Je0Je0Je0Je0Je0Je0Je0JgtenHcQyGQEQQQqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0kWiCuGaG4oIa04B7dLHdI0UySPU1+bXxhsinpxaJ+ztPZAiAQAAAAAAAAAAAAAAAAAAAAFN753qL3nNZYEmMaXPXT7QIBCKFEA0IABCsAt6tKs2ZiLn85ggNCjdx++vGIwNOI0X0OsXscSMgOBzCpMDGDOdt1ejV5LiPqorjd6fIIZG4PWCXjvjxCO+M=
MIIBMTCB6gYHKoZIzj0CATCB3gIBATArBgcqhkjOPQEBAiB/////////////////////////////////////////7TBEBCAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqYSRShRAQge0Je0Je0Je0Je0Je0Je0Je0Je0Je0Je0JgtenHcQyGQEQQQqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq0kWiCuGaG4oIa04B7dLHdI0UySPU1+bXxhsinpxaJ+ztPZAiAQAAAAAAAAAAAAAAAAAAAAFN753qL3nNZYEmMaXPXT7QIBCANCAAQrALerSrNmYi5/OYIDQo3cfvrxiMDTiNF9DrF7HEjIDgcwqTAxgznbdXo1eS4j6qK43enyCGRuD1gl4748Qjvj
但是,这对我来说似乎不正确。我读到 curve25519 公钥应该是 32 字节,这显然不是。我已经完成了尽职调查,并从谷歌中提取了几个示例并进行了尝试,但仍然遇到了同样的问题。任何帮助是极大的赞赏。
解决方案
Curve25519 不是 X9/Weierstrass 曲线。您所做的将与其他实现不兼容,这些实现都使用 Bernstein 对称为 X25519 的仅 X 蒙哥马利形式 Diffie-Hellman 或称为 Ed25519 的 Edwards 形式签名(通常没有预哈希)的规范。Java 对所有非对称密钥(公共和私有)使用的密钥编码不仅仅是密钥本身,而是一种包含元数据的通用编码,X.509 SPKI 或 PKCS8并通过首先将此曲线强制为 Weierstrass 形式(对于 X9)然后通过使用显式且长期过时的 X9 形式来生成未命名ECParameterSpec
的形式,您会极大地膨胀元数据。
取而代之的是使用算法 "X25519"
或"ED25519"
两者KeyPairGenerator
和后续KeyAgreement
或Signature
分别。标准编码仍将比原始密钥长,但要少得多。要获得原始密钥,在 Oracle/Open 中适当地使用{XEC,EdEC}{Public,Private}Key
由算法相关的实现(提供者)类实现的接口。(编辑)Recent Bouncy(1.65 以上)在足够新的 Java 上运行也可以做到这一点;否则,AFAICS 您必须获取通用 (ASN.1) 编码并对其进行解析——Bouncy 确实单独公开了该 (ASN.1) 功能(通过其“轻量级”API 而不是 JCA)(并且大约从一开始就已经存在)。
推荐阅读
- dataframe - 将列添加到 PySpark 数据框包含基于另外两列分组的列的标准偏差
- reactjs - 单击后退按钮 [Firefox] 后,Redux 商店似乎仍然保留一些数据
- dart - 如何使用 Flutter 并通过 iOS/Swift 和 Android/Kotlin 访问 Native SDKs 组件?
- .net - 新图像中 VB-NET 中的 tesseract OCR 错误
- sql - 具有复杂排序要求的访问查询
- javascript - JavaScript:根据条件创建二维对象数组
- google-apps-script - 使用函数循环遍历列,将结果放在表格旁边的列中
- c++ - 在裸函数内部 - 如何进行简单的赋值
- unity3d - 在 Unity 中识别特定对象碰撞
- mysql - ER模型中如何确定弱实体和强实体