com.yahoo.security.KeyUtils Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.security;
import org.bouncycastle.asn1.ASN1Encodable;
import org.bouncycastle.asn1.ASN1Primitive;
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.math.ec.ECPoint;
import org.bouncycastle.math.ec.FixedPointCombMultiplier;
import org.bouncycastle.math.ec.rfc7748.X25519;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMWriter;
import org.bouncycastle.util.Arrays;
import org.bouncycastle.util.io.pem.PemObject;
import javax.crypto.KeyAgreement;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.UncheckedIOException;
import java.math.BigInteger;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.XECPrivateKey;
import java.security.interfaces.XECPublicKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.NamedParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.security.spec.XECPrivateKeySpec;
import java.security.spec.XECPublicKeySpec;
import java.util.ArrayList;
import java.util.Base64;
import java.util.List;
import static com.yahoo.security.KeyAlgorithm.EC;
import static com.yahoo.security.KeyAlgorithm.RSA;
/**
* @author bjorncs
*/
public class KeyUtils {
private KeyUtils() {}
public static KeyPair generateKeypair(KeyAlgorithm algorithm, int keySize) {
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance(algorithm.getAlgorithmName(), BouncyCastleProviderHolder.getInstance());
if (keySize != -1) {
keyGen.initialize(keySize);
}
if (algorithm.getSpec().isPresent()) {
keyGen.initialize(algorithm.getSpec().get());
}
return keyGen.genKeyPair();
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
public static KeyPair generateKeypair(KeyAlgorithm algorithm) {
return generateKeypair(algorithm, -1);
}
public static PublicKey extractPublicKey(PrivateKey privateKey) {
String algorithm = privateKey.getAlgorithm();
try {
if (algorithm.equals(RSA.getAlgorithmName())) {
KeyFactory keyFactory = createKeyFactory(RSA);
RSAPrivateCrtKey rsaPrivateCrtKey = (RSAPrivateCrtKey) privateKey;
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(rsaPrivateCrtKey.getModulus(), rsaPrivateCrtKey.getPublicExponent());
return keyFactory.generatePublic(keySpec);
} else if (algorithm.equals(EC.getAlgorithmName())) {
KeyFactory keyFactory = createKeyFactory(EC);
BCECPrivateKey ecPrivateKey = (BCECPrivateKey) privateKey;
ECParameterSpec ecParameterSpec = ecPrivateKey.getParameters();
ECPoint ecPoint = new FixedPointCombMultiplier().multiply(ecParameterSpec.getG(), ecPrivateKey.getD());
ECPublicKeySpec keySpec = new ECPublicKeySpec(ecPoint, ecParameterSpec);
return keyFactory.generatePublic(keySpec);
} else {
throw new IllegalArgumentException("Unexpected key algorithm: " + algorithm);
}
} catch (GeneralSecurityException e) {
throw new RuntimeException(e);
}
}
public static KeyPair toKeyPair(PrivateKey privateKey) {
return new KeyPair(extractPublicKey(privateKey), privateKey);
}
public static KeyPair keyPairFromPemEncodedPrivateKey(String pem) {
return toKeyPair(fromPemEncodedPrivateKey(pem));
}
public static PrivateKey fromPemEncodedPrivateKey(String pem) {
try (PEMParser parser = new PEMParser(new StringReader(pem))) {
List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy