mirror of https://github.com/shred/acme4j
Add utility method to generate ECDSA key pairs
parent
f84c2cfe57
commit
6735d3b3f7
|
@ -16,10 +16,15 @@ package org.shredzone.acme4j.util;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.security.InvalidAlgorithmParameterException;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
import java.security.KeyPairGenerator;
|
import java.security.KeyPairGenerator;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.NoSuchProviderException;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
|
import org.bouncycastle.jce.ECNamedCurveTable;
|
||||||
|
import org.bouncycastle.jce.spec.ECParameterSpec;
|
||||||
import org.bouncycastle.openssl.PEMException;
|
import org.bouncycastle.openssl.PEMException;
|
||||||
import org.bouncycastle.openssl.PEMKeyPair;
|
import org.bouncycastle.openssl.PEMKeyPair;
|
||||||
import org.bouncycastle.openssl.PEMParser;
|
import org.bouncycastle.openssl.PEMParser;
|
||||||
|
@ -56,6 +61,26 @@ public class KeyPairUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new elliptic curve {@link KeyPair}.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* ECDSA curve name (e.g. "secp256r1")
|
||||||
|
* @return Generated {@link KeyPair}
|
||||||
|
*/
|
||||||
|
public static KeyPair createECKeyPair(String name) {
|
||||||
|
try {
|
||||||
|
ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(name);
|
||||||
|
KeyPairGenerator g = KeyPairGenerator.getInstance("ECDSA", "BC");
|
||||||
|
g.initialize(ecSpec, new SecureRandom());
|
||||||
|
return g.generateKeyPair();
|
||||||
|
} catch (NoSuchAlgorithmException | InvalidAlgorithmParameterException ex) {
|
||||||
|
throw new IllegalArgumentException("Invalid curve name " + name, ex);
|
||||||
|
} catch (NoSuchProviderException ex) {
|
||||||
|
throw new IllegalStateException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reads a {@link KeyPair} from a PEM file.
|
* Reads a {@link KeyPair} from a PEM file.
|
||||||
*
|
*
|
||||||
|
|
|
@ -20,8 +20,12 @@ import java.io.IOException;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.io.StringWriter;
|
import java.io.StringWriter;
|
||||||
import java.security.KeyPair;
|
import java.security.KeyPair;
|
||||||
|
import java.security.Security;
|
||||||
|
import java.security.interfaces.ECPublicKey;
|
||||||
import java.security.interfaces.RSAPublicKey;
|
import java.security.interfaces.RSAPublicKey;
|
||||||
|
|
||||||
|
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||||
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.jcabi.matchers.RegexMatchers;
|
import com.jcabi.matchers.RegexMatchers;
|
||||||
|
@ -33,6 +37,12 @@ import com.jcabi.matchers.RegexMatchers;
|
||||||
*/
|
*/
|
||||||
public class KeyPairUtilsTest {
|
public class KeyPairUtilsTest {
|
||||||
private static final int KEY_SIZE = 2048;
|
private static final int KEY_SIZE = 2048;
|
||||||
|
private static final String EC_CURVE = "secp256r1";
|
||||||
|
|
||||||
|
@BeforeClass
|
||||||
|
public static void setup() {
|
||||||
|
Security.addProvider(new BouncyCastleProvider());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test that RSA keypairs of the correct size are generated.
|
* Test that RSA keypairs of the correct size are generated.
|
||||||
|
@ -76,6 +86,50 @@ public class KeyPairUtilsTest {
|
||||||
|
|
||||||
// Verify that both keypairs are the same
|
// Verify that both keypairs are the same
|
||||||
assertThat(pair, not(sameInstance(readPair)));
|
assertThat(pair, not(sameInstance(readPair)));
|
||||||
|
assertThat(pair.getPublic().getEncoded(), is(equalTo(readPair.getPublic().getEncoded())));
|
||||||
|
assertThat(pair.getPrivate().getEncoded(), is(equalTo(readPair.getPrivate().getEncoded())));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that ECDSA keypairs are generated.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCreateECCKeyPair() {
|
||||||
|
KeyPair pair = KeyPairUtils.createECKeyPair(EC_CURVE);
|
||||||
|
assertThat(pair, is(notNullValue()));
|
||||||
|
assertThat(pair.getPublic(), is(instanceOf(ECPublicKey.class)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that reading and writing ECDSA keypairs work correctly.
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testWriteAndReadEC() throws IOException {
|
||||||
|
// Generate a test keypair
|
||||||
|
KeyPair pair = KeyPairUtils.createECKeyPair(EC_CURVE);
|
||||||
|
|
||||||
|
// Write keypair to PEM
|
||||||
|
String pem;
|
||||||
|
try (StringWriter out = new StringWriter()) {
|
||||||
|
KeyPairUtils.writeKeyPair(pair, out);
|
||||||
|
pem = out.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure PEM file is properly formatted
|
||||||
|
assertThat(pem, RegexMatchers.matchesPattern(
|
||||||
|
"-----BEGIN EC PRIVATE KEY-----[\\r\\n]+"
|
||||||
|
+ "([a-zA-Z0-9/+=]+[\\r\\n]+)+"
|
||||||
|
+ "-----END EC PRIVATE KEY-----[\\r\\n]*"));
|
||||||
|
|
||||||
|
// Read keypair from PEM
|
||||||
|
KeyPair readPair;
|
||||||
|
try (StringReader in = new StringReader(pem)) {
|
||||||
|
readPair = KeyPairUtils.readKeyPair(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify that both keypairs are the same
|
||||||
|
assertThat(pair, not(sameInstance(readPair)));
|
||||||
|
assertThat(pair.getPublic().getEncoded(), is(equalTo(readPair.getPublic().getEncoded())));
|
||||||
assertThat(pair.getPrivate().getEncoded(), is(equalTo(readPair.getPrivate().getEncoded())));
|
assertThat(pair.getPrivate().getEncoded(), is(equalTo(readPair.getPrivate().getEncoded())));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue