All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.bouncycastle.jcajce.ConsistentKeyPair Maven / Gradle / Ivy

Go to download

The FIPS 140-3 Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms certified to FIPS 140-3 level 1. This jar contains JCE provider and low-level API for the BC-FJA version 2.0.0, FIPS Certificate #4743. Please see certificate for certified platform details.

There is a newer version: 2.0.0
Show newest version
package org.bouncycastle.jcajce;

import java.math.BigInteger;
import java.security.AccessController;
import java.security.PrivateKey;
import java.security.PrivilegedAction;
import java.security.PublicKey;
import java.security.interfaces.DSAKey;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECKey;
import java.security.interfaces.ECPrivateKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;

import javax.crypto.interfaces.DHKey;
import javax.crypto.interfaces.DHPrivateKey;
import javax.crypto.interfaces.DHPublicKey;
import javax.crypto.spec.DHParameterSpec;

import org.bouncycastle.jcajce.interfaces.DSTU4145Key;
import org.bouncycastle.jcajce.interfaces.DSTU4145PrivateKey;
import org.bouncycastle.jcajce.interfaces.DSTU4145PublicKey;
import org.bouncycastle.jcajce.interfaces.ECGOST3410PrivateKey;
import org.bouncycastle.jcajce.interfaces.ECGOST3410PublicKey;
import org.bouncycastle.jcajce.interfaces.EdDSAKey;
import org.bouncycastle.jcajce.interfaces.GOST3410Key;
import org.bouncycastle.jcajce.interfaces.GOST3410PrivateKey;
import org.bouncycastle.jcajce.interfaces.GOST3410PublicKey;
import org.bouncycastle.jcajce.interfaces.XDHKey;
import org.bouncycastle.jcajce.spec.DSTU4145ParameterSpec;
import org.bouncycastle.jcajce.spec.ECDomainParameterSpec;
import org.bouncycastle.jcajce.spec.GOST3410DomainParameterSpec;
import org.bouncycastle.jcajce.spec.GOST3410ParameterSpec;
import org.bouncycastle.util.Arrays;

/**
 * Carrier class for a key pair which validates the consistency of the keys at construction time.
 */
public class ConsistentKeyPair
{
    private PrivateKey privateKey;
    private PublicKey publicKey;

    /**
     * Create a public/private key pair.
     *
     * @param publicKey the public key component.
     * @param privateKey the private key component.
     * @throws IllegalArgumentException if the public and private key arguments are inconsistent.
     */
    public ConsistentKeyPair(final PublicKey publicKey, final PrivateKey privateKey)
    {
        AccessController.doPrivileged(new PrivilegedAction()
        {
            public Object run()
            {
                checkKeyPairForConsistency(publicKey, privateKey);

                return null;
            }
        });

        this.publicKey = publicKey;
        this.privateKey = privateKey;
    }

    private void checkKeyPairForConsistency(PublicKey publicKey, PrivateKey privateKey)
    {
        if (publicKey instanceof ECKey && privateKey instanceof ECKey)
        {
            ECPrivateKey priv = (ECPrivateKey)privateKey;
            ECPublicKey pub = (ECPublicKey)publicKey;
            if (!priv.getParams().getCurve().equals(pub.getParams().getCurve())
                || !priv.getParams().getGenerator().equals(pub.getParams().getGenerator())
                || !priv.getParams().getOrder().equals(pub.getParams().getOrder())
                || priv.getParams().getCofactor() != pub.getParams().getCofactor())
            {
                throw new IllegalArgumentException("EC keys do not have the same domain parameters");
            }
            ECDomainParameterSpec spec = new ECDomainParameterSpec(priv.getParams());
            if (!spec.getDomainParameters().getG().multiply(priv.getS()).normalize().equals(
                spec.getDomainParameters().getCurve().createPoint(pub.getW().getAffineX(), pub.getW().getAffineY())))
            {
                throw new IllegalArgumentException("EC public key not consistent with EC private key");
            }
        }
        else if (publicKey instanceof DHKey && privateKey instanceof DHKey)
        {
            DHPrivateKey priv = (DHPrivateKey)privateKey;
            DHPublicKey pub = (DHPublicKey)publicKey;

            DHParameterSpec dhParameters = priv.getParams();
            if (!dhParameters.getG().equals(pub.getParams().getG())
                  && !dhParameters.getP().equals(pub.getParams().getP()))
            {
                throw new IllegalArgumentException("DH keys do not have the same domain parameters");
            }
            if (!dhParameters.getG().modPow(priv.getX(), dhParameters.getP()).equals(pub.getY()))
            {
                throw new IllegalArgumentException("DH public key not consistent with DH private key");
            }
        }
        else if (publicKey instanceof DSAKey && privateKey instanceof DSAKey)
        {
            DSAPrivateKey priv = (DSAPrivateKey)privateKey;
            DSAPublicKey pub = (DSAPublicKey)publicKey;

            DSAParams dsaParameters = priv.getParams();
            if (!dsaParameters.getG().equals(pub.getParams().getG())
                && !dsaParameters.getP().equals(pub.getParams().getP())
                && !dsaParameters.getQ().equals(pub.getParams().getQ()))
            {
                throw new IllegalArgumentException("DSA keys do not have the same domain parameters");
            }
            if (!dsaParameters.getG().modPow(priv.getX(), dsaParameters.getP()).equals(pub.getY()))
            {
                throw new IllegalArgumentException("DSA public key not consistent with DSA private key");
            }
        }
        else if (publicKey instanceof RSAKey && privateKey instanceof RSAKey)
        {
            RSAPrivateKey priv = (RSAPrivateKey)privateKey;
            RSAPublicKey pub = (RSAPublicKey)publicKey;

            if (!priv.getModulus().equals(pub.getModulus()))
            {
                throw new IllegalArgumentException("RSA keys do not have the same modulus");
            }
            BigInteger val = BigInteger.valueOf(2);
            if (!val.modPow(priv.getPrivateExponent(), priv.getModulus()).modPow(pub.getPublicExponent(), priv.getModulus()).equals(val))
            {
                throw new IllegalArgumentException("RSA public key not consistent with RSA private key");
            }
        }
        else if (publicKey instanceof GOST3410Key && privateKey instanceof GOST3410Key)
        {
            if (!((GOST3410Key)publicKey).getParams().equals(((GOST3410Key)privateKey).getParams()))
            {
                throw new IllegalArgumentException("GOST3410 parameters mismatch");
            }
            if (publicKey instanceof GOST3410PublicKey && privateKey instanceof GOST3410PrivateKey)
            {
                GOST3410PrivateKey priv = (GOST3410PrivateKey)privateKey;
                GOST3410PublicKey pub = (GOST3410PublicKey)publicKey;

                GOST3410ParameterSpec gostParameters = priv.getParams();
                GOST3410DomainParameterSpec gParams = (GOST3410DomainParameterSpec)gostParameters.getDomainParametersSpec();

                if (!gParams.getA().modPow(priv.getX(), gParams.getP()).equals(pub.getY()))
                {
                    throw new IllegalArgumentException("GOST3410 public key not consistent with GOST3410 private key");
                }
            }
            else if (publicKey instanceof ECGOST3410PublicKey && privateKey instanceof ECGOST3410PrivateKey)
            {
                ECGOST3410PrivateKey priv = (ECGOST3410PrivateKey)privateKey;
                ECGOST3410PublicKey pub = (ECGOST3410PublicKey)publicKey;

                GOST3410ParameterSpec gostParameters = priv.getParams();
                ECDomainParameterSpec gParams = (ECDomainParameterSpec)gostParameters.getDomainParametersSpec();
                ECDomainParameterSpec spec = new ECDomainParameterSpec(gParams);

                if (!spec.getDomainParameters().getG().multiply(priv.getS()).normalize().equals(
                    spec.getDomainParameters().getCurve().createPoint(pub.getW().getAffineX(), pub.getW().getAffineY())))
                {
                    throw new IllegalArgumentException("ECGOST3410 public key not consistent with ECGOST3410 private key");
                }
            }
            else
            {
                throw new IllegalArgumentException("GOST3410 key pair inconsistent");
            }
        }
        else if (publicKey instanceof DSTU4145Key && privateKey instanceof DSTU4145Key)
        {
            DSTU4145PrivateKey priv = (DSTU4145PrivateKey)privateKey;
            DSTU4145PublicKey pub = (DSTU4145PublicKey)publicKey;

            if (!priv.getParams().equals(pub.getParams()))
            {
                throw new IllegalArgumentException("DSTU4145 keys do not have the same domain parameters");
            }

            DSTU4145ParameterSpec dstu4145Parameters = priv.getParams();
            ECDomainParameterSpec spec = new ECDomainParameterSpec(dstu4145Parameters);

            if (!spec.getDomainParameters().getG().multiply(priv.getS()).negate().normalize().equals(
                spec.getDomainParameters().getCurve().createPoint(pub.getW().getAffineX(), pub.getW().getAffineY())))
            {
                throw new IllegalArgumentException("DSTU4145 public key not consistent with DSTU4145 private key");
            }
        }
        else if (publicKey instanceof EdDSAKey && privateKey instanceof EdDSAKey)
        {
            EdDSAKey priv = (EdDSAKey)privateKey;
            EdDSAKey pub = (EdDSAKey)publicKey;

            if (!priv.getAlgorithm().equals(pub.getAlgorithm()))
            {
                throw new IllegalArgumentException("EdDSA keys do not have the same domain parameters");
            }

            if (!Arrays.areEqual(priv.getPublicData(), pub.getPublicData()))
            {
                throw new IllegalArgumentException("EdDSA public key not consistent with EdDSA private key");
            }
        }
        else if (publicKey instanceof XDHKey && privateKey instanceof XDHKey)
        {
            XDHKey priv = (XDHKey)privateKey;
            XDHKey pub = (XDHKey)publicKey;

            if (!priv.getAlgorithm().equals(pub.getAlgorithm()))
            {
                throw new IllegalArgumentException("XDH keys do not have the same domain parameters");
            }

            if (!Arrays.areEqual(priv.getPublicData(), pub.getPublicData()))
            {
                throw new IllegalArgumentException("XDH public key not consistent with XDH private key");
            }
        }
        else
        {
            throw new IllegalArgumentException("Key pair inconsistent");
        }
    }

    /**
     * Return the public key component.
     *
     * @return the public key in the pair.
     */
    public PublicKey getPublic()
    {
        return this.publicKey;
    }

    /**
     * Return the private key component.
     *
     * @return the private key in the pair.
     */
    public PrivateKey getPrivate()
    {
        return this.privateKey;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy