asa*_*gar 5 java encryption cryptography
我想在我的项目中实现 ECDHE 算法,为此我想使用 Curve25519。但卡住了如何为 Curve25519 生成密钥对。使用其他曲线我能够生成密钥对,但是对于curve25519 获取算法未找到
我尝试使用以下代码:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC");
kpg.initialize(256);
KeyPair private_Key1 = kpg.generateKeyPair();
PublicKey ourPk1 = private_Key1.getPublic();
Run Code Online (Sandbox Code Playgroud)
Curve25519似乎从 Java 11 开始受支持(请注意,标准 Java 现在遵循 OpenJDK Java)。
链接到 JEP(Java 增强提案)还包含示例代码,逐字包含在此处:
KeyPairGenerator kpg = KeyPairGenerator.getInstance("XDH");
NamedParameterSpec paramSpec = new NamedParameterSpec("X25519");
kpg.initialize(paramSpec); // equivalent to kpg.initialize(255)
// alternatively: kpg = KeyPairGenerator.getInstance("X25519")
KeyPair kp = kpg.generateKeyPair();
KeyFactory kf = KeyFactory.getInstance("XDH");
BigInteger u = ...
XECPublicKeySpec pubSpec = new XECPublicKeySpec(paramSpec, u);
PublicKey pubKey = kf.generatePublic(pubSpec);
KeyAgreement ka = KeyAgreement.getInstance("XDH");
ka.init(kp.getPrivate());
ka.doPhase(pubKey, true);
byte[] secret = ka.generateSecret();
Run Code Online (Sandbox Code Playgroud)
注意,密钥工厂生成的公钥是对方的公钥。通常您会从字节中解码该值。
您可以使用BouncyCastle支持此曲线的加密提供程序:
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 java.security.InvalidAlgorithmParameterException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
public class Test {
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidAlgorithmParameterException {
X9ECParameters curveParams = CustomNamedCurves.getByName("Curve25519");
ECParameterSpec ecSpec = new ECParameterSpec(curveParams.getCurve(), curveParams.getG(), curveParams.getN(), curveParams.getH(), curveParams.getSeed());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());
kpg.initialize(ecSpec);
KeyPair keyPair = kpg.generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
}
}
Run Code Online (Sandbox Code Playgroud)
要提取原始x和(y公钥ECPoint),您可以使用以下代码:
byte[] encoded = publicKey.getEncoded();
ASN1Sequence asn1Primitive = ASN1Sequence.getInstance(encoded);
ASN1Encodable algorithmIdentifier = asn1Primitive.getObjectAt(0);
DERBitString ecPointBitString = (DERBitString) asn1Primitive.getObjectAt(1);
//use curve parameters from previous code snippet
ECPoint ecPoint = curveParams.getCurve().decodePoint(ecPointBitString.getOctets());
byte[] x = ecPoint.getAffineXCoord().getEncoded();
byte[] y = ecPoint.getAffineYCoord().getEncoded();
Run Code Online (Sandbox Code Playgroud)
这基本上是解析RFC5480SubjectPublicKeyInfo中描述的编码
BCECPrivateKey privateKey1 = (BCECPrivateKey) privateKey;
byte[] bigIntPk = privateKey1.getS().toByteArray();
Run Code Online (Sandbox Code Playgroud)
或者通过解析 DER 对象:
ASN1Sequence instance = ASN1Sequence.getInstance(privateKey.getEncoded());
DEROctetString pkOctetString = (DEROctetString) instance.getObjectAt(2);
ASN1Sequence ecPkSequence = DERSequence.getInstance(pkOctetString.getOctets());
DEROctetString pkOctets = (DEROctetString) ecPkSequence.getObjectAt(1);
byte[] bigIntPk = new BigInteger(1, pkOctets.getOctets()).toByteArray();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2168 次 |
| 最近记录: |