下面列出了怎么用java.security.interfaces.ECPrivateKey的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
public void testEncodedPrivateKey() throws Exception {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(EcUtil.getNistP256Params());
KeyPair keyPair = keyGen.generateKeyPair();
ECPrivateKey priv = (ECPrivateKey) keyPair.getPrivate();
byte[] encoded = priv.getEncoded();
System.out.println("Encoded ECPrivateKey:" + TestUtil.bytesToHex(encoded));
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(encoded);
KeyFactory kf = KeyFactory.getInstance("EC");
ECPrivateKey decoded = (ECPrivateKey) kf.generatePrivate(spec);
assertEquals(priv.getS(), decoded.getS());
assertEquals(priv.getParams().getCofactor(), decoded.getParams().getCofactor());
assertEquals(priv.getParams().getCurve(), decoded.getParams().getCurve());
assertEquals(priv.getParams().getGenerator(), decoded.getParams().getGenerator());
assertEquals(priv.getParams().getOrder(), decoded.getParams().getOrder());
}
private PublicKey getPublicKeyFromPrivateEC(DerValue bitString, ECPrivateKey privateKey) throws InvalidKeySpecException, IOException, NoSuchAlgorithmException {
// Build an X.509 DER encoded byte array from the provided bitString
//
// SubjectPublicKeyInfo ::= SEQUENCE {
// algorithm AlgorithmIdentifier,
// subjectPublicKey BIT STRING
// }
DerValue[] sequence = new DerInputStream(privateKey.getEncoded()).getSequence();
byte[] encodedPublicKey = new DerOutputStream()
.writeValue(new DerValue(Tag.Sequence, new DerOutputStream()
.writeValue(new DerValue(Tag.Sequence, sequence[1].toByteArray()))
.writeValue(new DerValue(Tag.BitString, bitString.toByteArray()))))
.toByteArray();
return KeyFactory.getInstance("EC").generatePublic(new X509EncodedKeySpec(encodedPublicKey));
}
static String keyAlgorithm(Map<String, Object> headers, Key signingKey) {
String alg = (String) headers.get("alg");
if (signingKey instanceof RSAPrivateKey) {
if (alg == null) {
return SignatureAlgorithm.RS256.name();
} else if (alg.startsWith("RS")) {
return alg;
}
} else if (signingKey instanceof ECPrivateKey) {
if (alg == null) {
return SignatureAlgorithm.ES256.name();
} else if (alg.startsWith("ES")) {
return alg;
}
} else if (signingKey instanceof SecretKey) {
if (alg == null) {
return SignatureAlgorithm.HS256.name();
} else if (alg.startsWith("HS")) {
return alg;
}
}
throw ImplMessages.msg.unsupportedSignatureAlgorithm(signingKey.getAlgorithm());
}
@Test
public void shouldThrowOnVerifyWhenTheSignatureIsNotPrepared() throws Exception {
exception.expect(SignatureVerificationException.class);
exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg");
exception.expectCause(isA(SignatureException.class));
CryptoHelper crypto = mock(CryptoHelper.class);
when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(String.class), any(String.class), any(byte[].class)))
.thenThrow(SignatureException.class);
ECPublicKey publicKey = mock(ECPublicKey.class);
ECPrivateKey privateKey = mock(ECPrivateKey.class);
ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey);
Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider);
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g";
algorithm.verify(JWT.decode(jwt));
}
public static <T extends Key> void assertKeyEquals(String message, T expected, T actual) {
if (expected == actual) {
return;
}
assertEquals(message + "[algorithm]", expected.getAlgorithm(), actual.getAlgorithm());
if (expected instanceof RSAPublicKey) {
assertRSAPublicKeyEquals(message, RSAPublicKey.class.cast(expected), RSAPublicKey.class.cast(actual));
} else if (expected instanceof DSAPublicKey) {
assertDSAPublicKeyEquals(message, DSAPublicKey.class.cast(expected), DSAPublicKey.class.cast(actual));
} else if (expected instanceof ECPublicKey) {
assertECPublicKeyEquals(message, ECPublicKey.class.cast(expected), ECPublicKey.class.cast(actual));
} else if (expected instanceof RSAPrivateKey) {
assertRSAPrivateKeyEquals(message, RSAPrivateKey.class.cast(expected), RSAPrivateKey.class.cast(actual));
} else if (expected instanceof ECPrivateKey) {
assertECPrivateKeyEquals(message, ECPrivateKey.class.cast(expected), ECPrivateKey.class.cast(actual));
}
assertArrayEquals(message + "[encdoded-data]", expected.getEncoded(), actual.getEncoded());
}
@Test
public void shouldFailJOSEToDERConversionOnInvalidJOSESignatureLength() throws Exception {
exception.expect(SignatureVerificationException.class);
exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA");
exception.expectCause(isA(SignatureException.class));
exception.expectCause(hasMessage(is("Invalid JOSE signature format.")));
byte[] bytes = new byte[256];
new SecureRandom().nextBytes(bytes);
String signature = Base64.encodeBase64URLSafeString(bytes);
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
ECPublicKey publicKey = (ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC");
ECPrivateKey privateKey = mock(ECPrivateKey.class);
ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey);
Algorithm algorithm = new ECDSAAlgorithm("ES256", "SHA256withECDSA", 128, provider);
algorithm.verify(JWT.decode(jwt));
}
@Test
public void testToJsonWebKey() throws Exception {
ECGenParameterSpec gps = new ECGenParameterSpec(EcKey.P521);
EC_KEY_GENERATOR.initialize(gps);
KeyPair keyPair = EC_KEY_GENERATOR.generateKeyPair();
ECPublicKey apub = (ECPublicKey) keyPair.getPublic();
ECPoint point = apub.getW();
ECPrivateKey apriv = (ECPrivateKey) keyPair.getPrivate();
JsonWebKey jwk = new JsonWebKey()
.withKid("kid")
.withCrv(JsonWebKeyCurveName.P_521)
.withX(point.getAffineX().toByteArray())
.withY(point.getAffineY().toByteArray())
.withD(apriv.getS().toByteArray())
.withKty(JsonWebKeyType.EC);
EcKey newKey = new EcKey("kid", keyPair);
JsonWebKey newJwk = newKey.toJsonWebKey();
//set missing parameters
newJwk.withKid("kid");
assertEquals(jwk, newJwk);
}
public static ECDHKeySet getSharedSecret (ECKey keyServer, ECKey keyClient) {
try {
ECPrivateKeySpec specPrivate = new ECPrivateKeySpec(keyServer.getPrivKey(), ecParameters);
ECPublicKeySpec specPublic = new ECPublicKeySpec(new ECPoint(keyClient.getPubKeyPoint().getXCoord().toBigInteger(), keyClient.getPubKeyPoint()
.getYCoord().toBigInteger()), ecParameters);
ECPrivateKey privateKey = (ECPrivateKey) kf.generatePrivate(specPrivate);
ECPublicKey publicKey = (ECPublicKey) kf.generatePublic(specPublic);
JCEECPrivateKey ecPrivKey = new JCEECPrivateKey(privateKey);
JCEECPublicKey ecPubKey = new JCEECPublicKey(publicKey);
KeyAgreement aKeyAgree = KeyAgreement.getInstance("ECDH");
aKeyAgree.init(ecPrivKey);
aKeyAgree.doPhase(ecPubKey, true);
return new ECDHKeySet(aKeyAgree.generateSecret(), keyServer.getPubKey(), keyClient.getPubKey());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public byte[] getDerivedKey(JweHeaders headers) {
KeyPair pair = CryptoUtils.generateECKeyPair(ecurve);
ECPublicKey publicKey = (ECPublicKey)pair.getPublic();
ECPrivateKey privateKey = (ECPrivateKey)pair.getPrivate();
KeyAlgorithm keyAlgo = headers.getKeyEncryptionAlgorithm();
ContentAlgorithm contentAlgo = ContentAlgorithm.valueOf(ctAlgo);
String algorithm = (KeyAlgorithm.isDirect(keyAlgo)) ? contentAlgo.getJwaName() : keyAlgo.getJwaName();
int keySizeBits = (KeyAlgorithm.isDirect(keyAlgo)) ? contentAlgo.getKeySizeBits() : keyAlgo.getKeySizeBits();
if (apuBytes != null) {
headers.setHeader("apu", Base64UrlUtility.encode(apuBytes));
}
if (apvBytes != null) {
headers.setHeader("apv", Base64UrlUtility.encode(apvBytes));
}
headers.setJsonWebKey("epk", JwkUtils.fromECPublicKey(publicKey, ecurve));
return JweUtils.getECDHKey(privateKey, peerPublicKey, apuBytes, apvBytes,
algorithm, keySizeBits);
}
@Test
public void shouldFailJOSEToDERConversionOnInvalidJOSESignatureLength() throws Exception {
exception.expect(SignatureVerificationException.class);
exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: SHA256withECDSA");
exception.expectCause(isA(SignatureException.class));
exception.expectCause(hasMessage(is("Invalid JOSE signature format.")));
byte[] bytes = new byte[256];
new SecureRandom().nextBytes(bytes);
String signature = Base64.encodeBase64URLSafeString(bytes);
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9." + signature;
ECPublicKey publicKey = (ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC");
ECPrivateKey privateKey = mock(ECPrivateKey.class);
ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey);
Algorithm algorithm = new ECDSAAlgorithm("ES256", "SHA256withECDSA", 128, provider);
algorithm.verify(JWT.decode(jwt));
}
@Test
public void shouldDecodeECDSA384DER() throws Exception {
ECDSAAlgorithm algorithm384 = (ECDSAAlgorithm) Algorithm.ECDSA384((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_384, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_384, "EC"));
//Without padding
byte[] derSignature = createDERSignature(48, false, false);
byte[] joseSignature = algorithm384.DERToJOSE(derSignature);
assertValidJOSESignature(joseSignature, 48, false, false);
//With R padding
derSignature = createDERSignature(48, true, false);
joseSignature = algorithm384.DERToJOSE(derSignature);
assertValidJOSESignature(joseSignature, 48, true, false);
//With S padding
derSignature = createDERSignature(48, false, true);
joseSignature = algorithm384.DERToJOSE(derSignature);
assertValidJOSESignature(joseSignature, 48, false, true);
//With both paddings
derSignature = createDERSignature(48, true, true);
joseSignature = algorithm384.DERToJOSE(derSignature);
assertValidJOSESignature(joseSignature, 48, true, true);
}
@Test
public void shouldThrowOnSignWhenTheSignatureIsNotPrepared() throws Exception {
exception.expect(SignatureGenerationException.class);
exception.expectMessage("The Token's Signature couldn't be generated when signing using the Algorithm: some-algorithm");
exception.expectCause(isA(SignatureException.class));
CryptoHelper crypto = mock(CryptoHelper.class);
when(crypto.createSignatureFor(anyString(), any(PrivateKey.class), any(byte[].class), any(byte[].class)))
.thenThrow(SignatureException.class);
ECPublicKey publicKey = mock(ECPublicKey.class);
ECPrivateKey privateKey = mock(ECPrivateKey.class);
ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey);
Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider);
algorithm.sign(ES256HeaderBytes, new byte[0]);
}
/**
* Sends a LOAD KEY APDU. The given private key and chain code are formatted as a raw binary seed and the P1 of
* the command is set to LOAD_KEY_P1_SEED (0x03). This works on cards which support public key derivation.
* The loaded keyset is extended and support further key derivation.
*
* @param aPrivate a private key
* @param chainCode the chain code
* @return the raw card response
* @throws IOException communication error
*/
public APDUResponse loadKey(PrivateKey aPrivate, byte[] chainCode) throws IOException {
byte[] privateKey = ((ECPrivateKey) aPrivate).getS().toByteArray();
int privLen = privateKey.length;
int privOff = 0;
if(privateKey[0] == 0x00) {
privOff++;
privLen--;
}
byte[] data = new byte[chainCode.length + privLen];
System.arraycopy(privateKey, privOff, data, 0, privLen);
System.arraycopy(chainCode, 0, data, privLen, chainCode.length);
return loadKey(data, LOAD_KEY_P1_SEED);
}
@Test
public void shouldThrowOnVerifyWhenThePublicKeyIsInvalid() throws Exception {
exception.expect(SignatureVerificationException.class);
exception.expectMessage("The Token's Signature resulted invalid when verified using the Algorithm: some-alg");
exception.expectCause(isA(InvalidKeyException.class));
CryptoHelper crypto = mock(CryptoHelper.class);
when(crypto.verifySignatureFor(anyString(), any(PublicKey.class), any(String.class), any(String.class), any(byte[].class)))
.thenThrow(InvalidKeyException.class);
ECPublicKey publicKey = mock(ECPublicKey.class);
ECPrivateKey privateKey = mock(ECPrivateKey.class);
ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey);
Algorithm algorithm = new ECDSAAlgorithm(crypto, "some-alg", "some-algorithm", 32, provider);
String jwt = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9.4iVk3-Y0v4RT4_9IaQlp-8dZ_4fsTzIylgrPTDLrEvTHBTyVS3tgPbr2_IZfLETtiKRqCg0aQ5sh9eIsTTwB1g";
algorithm.verify(JWT.decode(jwt));
}
public BCECPrivateKey(
ECPrivateKey key,
ProviderConfiguration configuration)
{
this.d = key.getS();
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
this.configuration = configuration;
}
public BCECPrivateKey(
ECPrivateKey key,
ProviderConfiguration configuration)
{
this.d = key.getS();
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
this.configuration = configuration;
}
@Test
public void shouldDoECDSA512SigningWithBothKeys() throws Exception {
Algorithm algorithm = Algorithm.ECDSA512((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC"));
String jwt = asJWT(algorithm, ES512Header, auth0IssPayload);
assertSignaturePresent(jwt);
algorithm.verify(JWT.decode(jwt));
}
@Test
public void shouldDoECDSA512SigningWithProvidedPrivateKey() throws Exception {
ECDSAKeyProvider provider = mock(ECDSAKeyProvider.class);
PrivateKey privateKey = readPrivateKeyFromFile(PRIVATE_KEY_FILE_512, "EC");
PublicKey publicKey = readPublicKeyFromFile(PUBLIC_KEY_FILE_512, "EC");
when(provider.getPrivateKey()).thenReturn((ECPrivateKey) privateKey);
when(provider.getPublicKeyById(null)).thenReturn((ECPublicKey) publicKey);
Algorithm algorithm = Algorithm.ECDSA512(provider);
String jwt = asJWT(algorithm, ES512Header, auth0IssPayload);
assertSignaturePresent(jwt);
algorithm.verify(JWT.decode(jwt));
}
public static EC2COSEKey create(KeyPair keyPair, COSEAlgorithmIdentifier alg) {
if (keyPair != null && keyPair.getPrivate() instanceof ECPrivateKey && keyPair.getPublic() instanceof ECPublicKey) {
ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
ECPublicKey ecPublicKey = (ECPublicKey) keyPair.getPublic();
ECPoint ecPoint = ecPublicKey.getW();
Curve curve = getCurve(ecPrivateKey.getParams());
byte[] x = ECUtil.convertToFixedByteArray(curve.getSize(), ecPoint.getAffineX());
byte[] y = ECUtil.convertToFixedByteArray(curve.getSize(), ecPoint.getAffineY());
byte[] d = ecPrivateKey.getS().toByteArray();
return new EC2COSEKey(null, alg, null, curve, x, y, d);
} else {
throw new IllegalArgumentException();
}
}
@Test
public void shouldThrowOnDERSignatureConversionIfDoesNotStartWithCorrectSequenceByte() throws Exception {
exception.expect(SignatureException.class);
exception.expectMessage("Invalid DER signature format.");
ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC"));
String content256 = "eyJhbGciOiJFUzI1NiJ9.eyJpc3MiOiJhdXRoMCJ9";
byte[] signature = algorithm256.sign(content256.getBytes(), new byte[0]);
signature[0] = (byte) 0x02;
algorithm256.DERToJOSE(signature);
}
@Test
void hasPublicKey_test() {
EC2COSEKey keyPair = EC2COSEKey.create(ECUtil.createKeyPair());
EC2COSEKey privateKey = EC2COSEKey.create((ECPrivateKey) ECUtil.createKeyPair().getPrivate());
EC2COSEKey publicKey = EC2COSEKey.create((ECPublicKey) ECUtil.createKeyPair().getPublic());
assertThat(keyPair.hasPublicKey()).isTrue();
assertThat(privateKey.hasPublicKey()).isFalse();
assertThat(publicKey.hasPublicKey()).isTrue();
}
@Test
public void shouldThrowOnDERSignatureConversionIfSNumberDoesNotHaveExpectedLength() throws Exception {
ECDSAAlgorithm algorithm256 = (ECDSAAlgorithm) Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC"));
byte[] derSignature = createDERSignature(32, false, false);
derSignature[4 + 32 + 1] = (byte) 34;
exception.expect(SignatureException.class);
exception.expectMessage("Invalid DER signature format.");
algorithm256.DERToJOSE(derSignature);
}
@Test
public void shouldReturnNullSigningKeyIdIfCreatedWithDefaultProvider() throws Exception {
ECPublicKey publicKey = mock(ECPublicKey.class);
ECPrivateKey privateKey = mock(ECPrivateKey.class);
ECDSAKeyProvider provider = ECDSAAlgorithm.providerForKeys(publicKey, privateKey);
Algorithm algorithm = new ECDSAAlgorithm("some-alg", "some-algorithm", 32, provider);
assertThat(algorithm.getSigningKeyId(), is(nullValue()));
}
public BCECGOST3410PrivateKey(
ECPrivateKey key)
{
this.d = key.getS();
this.algorithm = key.getAlgorithm();
this.ecSpec = key.getParams();
}
public static void assertECPrivateKeyEquals(String message, ECPrivateKey expected, ECPrivateKey actual) {
if (expected == actual) {
return;
}
assertEquals(message + "[S]", expected.getS(), actual.getS());
assertECParameterSpecEquals(message, expected, actual);
}
private static KeyPair generateDefaultKeyPair() {
KeyPair keyPair = null;
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("EC");
keyGen.initialize(256);
keyPair = keyGen.generateKeyPair();
ECPrivateKey ecPrivateKey = (ECPrivateKey) keyPair.getPrivate();
ecPrivateKey.getEncoded();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return keyPair;
}
public static void writeObject(final Object object, final PemWriter writer)
throws IOException, CertificateEncodingException {
final String description;
if (object instanceof Certificate) {
description = "CERTIFICATE";
} else if (object instanceof RSAPrivateKey) {
description = "PAILLIER PRIVATE KEY";
} else if (object instanceof RSAPublicKey) {
description = "PAILLIER PUBLIC KEY";
} else if (object instanceof ECPrivateKey) {
description = "EC PRIVATE KEY";
} else if (object instanceof ECPublicKey) {
description = "EC PUBLIC KEY";
} else if (object instanceof EdDSAPrivateKey) {
description = "ED25519 PRIVATE KEY";
} else if (object instanceof EdDSAPublicKey) {
description = "ED25519 PUBLIC KEY";
} else if (object instanceof PrivateKey) {
description = "PRIVATE KEY";
} else if (object instanceof PublicKey) {
description = "PUBLIC KEY";
} else if (object instanceof Key) {
description = "KEY";
} else {
throw new IllegalArgumentException("Unknwon object type");
}
final byte[] encoded = (object instanceof Key) ? ((Key) object).getEncoded()
: ((Certificate) object).getEncoded();
writer.writeObject(new PemObject(description, encoded));
}
protected static byte[] decrypt(final byte[] ciphertext, final PrivateKey privateKey)
throws BadPaddingException, IllegalBlockSizeException {
if (privateKey instanceof ECPrivateKey) {
final ECPrivateKey ecPrivateKey = (ECPrivateKey) privateKey;
final BigInteger privateKeyInt = ecPrivateKey.getS();
return decrypt(ciphertext, privateKeyInt);
} else {
throw new IllegalArgumentException("Key type must be ECPublicKey!");
}
}
@Test
public void shouldDoECDSA256SigningWithBothKeys() throws Exception {
Algorithm algorithm = Algorithm.ECDSA256((ECPublicKey) readPublicKeyFromFile(PUBLIC_KEY_FILE_256, "EC"), (ECPrivateKey) readPrivateKeyFromFile(PRIVATE_KEY_FILE_256, "EC"));
byte[] signatureBytes = algorithm.sign(ES256HeaderBytes, auth0IssPayloadBytes);
String jwtSignature = Base64.encodeBase64URLSafeString(signatureBytes);
String jwt = String.format("%s.%s.%s", ES256Header, auth0IssPayload, jwtSignature);
assertSignaturePresent(jwt);
algorithm.verify(JWT.decode(jwt));
}
public static JWSObject forgeSkinData(KeyPair pair, JSONObject skinData) {
URI x5u = URI.create(Base64.getEncoder().encodeToString(pair.getPublic().getEncoded()));
JWSHeader header = new JWSHeader.Builder(JWSAlgorithm.ES384).x509CertURL(x5u).build();
JWSObject jws = new JWSObject(header, new Payload(skinData));
try {
EncryptionUtils.signJwt(jws, (ECPrivateKey) pair.getPrivate());
} catch (JOSEException e) {
throw new RuntimeException(e);
}
return jws;
}