EdDSA(Edwards-curve Digital Signature Algorithm)๋ Edwards-Curve
๊ณก์ ์ ์ํ ์ ์ ์๋ช
์๊ณ ๋ฆฌ์ฆ์ ์๋ฏธํ๋ค. ๊ณผ๊ฑฐ์ ED25519์ ๋ํด์ ์ ๋ฆฌํ ๊ฒ๊ณผ ๊ฐ์ด ECDSA์ ํผ๋์ด ๋ ์ ์๋ค. RFC8410์์๋ Internet X.509 Public Key Infrastructure ์์ Ed25519๊ณผ ๊ฐ์ Algorithm Identifiers์ ๋ํ ํ์ค์ ์ค๋ช
ํ๊ณ ์๋ค.
Curve25519 and Curve448 Algorithm Identifiers โ
BC(Bouncy Castle)์ ECNamedCurveTable.getNames()
์๋ ๊ธฐ๋ณธ์ ์ธ EC ๊ณก์ ์ด ํฌํจ๋์ด์๊ณ curve25519
๋ CustomNamedCurves์ ํฌํจ๋์ด ์์ด Curve25519 ๊ณก์ ์ ๋ํ X9ECParameters๋ฅผ ์๋์ ๊ฐ์ด ECParameterSpec์ผ๋ก ๋ณ๊ฒฝํ ์ ์๋ค.
public static AlgorithmParameterSpec curve25519Spec() {
// NOTE: Ed25519 not contains in ECNamedCurveTable.getNames()
X9ECParameters ecP = CustomNamedCurves.getByName("curve25519");
return new ECParameterSpec(ecP.getCurve(), ecP.getG(), ecP.getN(), ecP.getH(), ecP.getSeed());
}
Ed25519 ํค ํ์ด ์์ฑ โ
Ed25519KeyPairGenerator
์ ํจ๊ป ECKeyGenerationParameters
๋ฅผ ์ฌ์ฉํ๋ฉด Ed25519 ํค ํ์ด๋ฅผ ์์ฑํ ์ ์๋ค. ๊ทธ๋ฐ๋ฐ ์ด๋ฏธ Ed25519KeyGenerationParameters๋ฅผ ์ ๊ณตํ๊ณ ์์ผ๋ฏ๋ก ๊ตณ์ด ECParameterSpec๋ฅผ ์ฌ์ฉํ๋ ์ฝ๋๋ฅผ ์์ฑํ ํ์๊ฐ ์๋ค. ๋ง์ฝ, ๊ตณ์ด ECParameterSpec์ผ๋ก ECKeyGenerationParameters๋ฅผ ๋ง๋ค์ด์ ์ฌ์ฉํ๊ณ ์ถ์ ์ฌ๋๋ค์ ์ํด ์์ ์ฝ๋๋ฅผ ์ฒจ๋ถํ๋ค.
@Test
void TestKeyPairUsingEd25519Generator() {
Ed25519KeyPairGenerator keyPairGenerator = new Ed25519KeyPairGenerator();
keyPairGenerator.init(new Ed25519KeyGenerationParameters(new SecureRandom()));
AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair();
}
@Test
void TestKeyPairUsingECParams() {
ECParameterSpec curve25519Spec = (ECParameterSpec) curve25519Spec();
ECDomainParameters ecParams = new ECDomainParameters(curve25519Spec.getCurve(), curve25519Spec.getG(), curve25519Spec.getN(), curve25519Spec.getH());
ECKeyGenerationParameters ecKeyGenerationParameters = new ECKeyGenerationParameters(ecParams, new SecureRandom());
Ed25519KeyPairGenerator keyPairGenerator = new Ed25519KeyPairGenerator();
keyPairGenerator.init(ecKeyGenerationParameters);
AsymmetricCipherKeyPair keyPair = keyPairGenerator.generateKeyPair();
}
Ed25519PrivateKeyParameters๋ฅผ PrivateKey๋ก ๋ณํ โ
ํด๋ผ์ด์ธํธ์ X.509 ์ธ์ฆ์๋ฅผ ๋ง๋๋ ๊ฒฝ์ฐ ์๋ช
์ ์ํ PrivateKey๊ฐ ํ์ํ๋ฐ ์ง์ ์ ์ผ๋ก ๋ณํํ ์๊ฐ ์์ผ๋ฏ๋ก KeyFactorySpi.Ed25519
์ PrivateKeyInfoFactory
๋ฅผ ์ฌ์ฉํด์ Ed25519PrivateKeyParameters๋ก ๋์ด์๋ ๋น๋ฐํค๋ฅผ PrivateKey ํด๋์ค๋ก ๋ณ๊ฒฝํด์ผ ํ๋ค.
// NOTE: AsymmetricCipherKeyPair keyPair
Ed25519PrivateKeyParameters privateKeyP = (Ed25519PrivateKeyParameters) keyPair.getPrivate();
KeyFactorySpi.Ed25519 keyFactory = new KeyFactorySpi.Ed25519();
PrivateKey privateKey = keyFactory.generatePrivate(PrivateKeyInfoFactory.createPrivateKeyInfo(privateKeyP));
๊ณต๊ฐํค๋ฅผ SubjectPublicKeyInfoFactory๋ก ๋ณํ โ
Ed25519PublicKeyParameters๋ก ๋์ด์๋ ๊ณต๊ฐํค๋ฅผ SubjectPublicKeyInfo๋ก ๋ณํํ๋ ๊ฒ์ SubjectPublicKeyInfoFactory
ํด๋์ค์์ ์ ๊ณตํ๊ณ ์๋ค. ์์ ๋น๋ฐํค์ฒ๋ผ KeyFactorySpi.Ed25519๋ฅผ ์ฌ์ฉํด์ PublicKey๋ก ๋ณํํ ํ์๋ ์์ ๊ฒ ๊ฐ๋ค.
// NOTE: AsymmetricCipherKeyPair keyPair
Ed25519PublicKeyParameters publicKeyP = (Ed25519PublicKeyParameters) keyPair.getPublic();
SubjectPublicKeyInfo publicKeyInfo = SubjectPublicKeyInfoFactory.createSubjectPublicKeyInfo(publicKeyP);
EdDSA Signatures โ
Curve25519์ Curve448๋ฅผ ์ฌ์ฉํ EdDSA๋ ๊ฐ๊ฐ Ed25519
์ Ed448
์ด๋ผ๋ ์๋ช
์๊ณ ๋ฆฌ์ฆ์ผ๋ก ํํํ๋ค. ์์, PrivateKey์ SubjectPublickKeyInfo๋ก ๋ณํํ ์ํ์ด๋ฏ๋ก X.509 ์ธ์ฆ์๋ฅผ ๋ง๋๋ ๊ฒ์ ์ด๋ ต์ง ์์ ๊ฒ์ด๋ค.
X500Name issuer = new X500Name("CN=Mambo");
BigInteger serialNumber = new BigInteger(128, new SecureRandom());
ZonedDateTime now = ZonedDateTime.now();
Date notBefore = Date.from(now.toInstant());
Date notAfter = Date.from(now.plus(1, ChronoUnit.YEARS).toInstant());
ContentSigner contentSigner = new JcaContentSignerBuilder("Ed25519").setProvider(BouncyCastleProvider.PROVIDER_NAME).build(privateKey);
X509CertificateHolder certificateHolder = new JcaX509v3CertificateBuilder(issuer, serialNumber, notBefore, notAfter, issuer, publicKeyInfo).build(contentSigner);
X509Certificate certificate = new JcaX509CertificateConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME).getCertificate(certificateHolder);
certificate.checkValidity(new Date());
KeyPairGeneratorSpi๋ก Ed25519 ํค ํ์ด ์์ฑ โ
์ฌ์ค์ BC์์ KeyPairGeneratorSpi๋ฅผ ์ ๊ณตํ๊ณ ์์ผ๋ฏ๋ก ์๋์ ๊ฐ์ด BCEdDSAPrivateKey
์ BCEdDSAPublicKey
๋ฅผ ๊ฐ์ง๋ ํค ํ์ด๋ฅผ ์์ฑํ ์ ์๋ค.
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("Ed25519", BouncyCastleProvider.PROVIDER_NAME);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
๋ ์์ธํ ์ฝ๋๋ EdDSATest.java์์ ํ์ธํ ์ ์๋ค.