co.lqnt.lockbox.key.PrivateKey.java Source code

Java tutorial

Introduction

Here is the source code for co.lqnt.lockbox.key.PrivateKey.java

Source

/*
 * This file is part of the Lockbox package.
 *
 * Copyright  2013 Erin Millard
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

package co.lqnt.lockbox.key;

import co.lqnt.lockbox.util.PemWriterFactory;
import co.lqnt.lockbox.util.PemWriterFactoryInterface;
import co.lqnt.lockbox.util.PrivateKeyInformationFactory;
import co.lqnt.lockbox.util.PrivateKeyInformationFactoryInterface;
import co.lqnt.lockbox.util.StringWriterFactory;
import co.lqnt.lockbox.util.StringWriterFactoryInterface;
import java.io.IOException;
import java.io.StringWriter;
import java.math.BigInteger;
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
import org.bouncycastle.asn1.pkcs.RSAPrivateKey;
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
import org.bouncycastle.crypto.params.RSAPrivateCrtKeyParameters;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.openssl.PEMEncryptor;
import org.bouncycastle.openssl.PEMException;
import org.bouncycastle.openssl.PEMWriter;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import org.bouncycastle.openssl.jcajce.JcePEMEncryptorBuilder;

/**
 * Represents a Lockbox private key.
 */
public class PrivateKey implements PrivateKeyInterface {
    /**
     * Construct a new Lockbox private key.
     *
     * @param modulus         The modulus.
     * @param publicExponent  The public exponent.
     * @param privateExponent The private exponent.
     * @param prime1          The first prime, or 'P'.
     * @param prime2          The second prime, or 'Q'.
     * @param primeExponent1  The first prime exponent, or 'DP'.
     * @param primeExponent2  The first prime exponent, or 'DQ'.
     * @param coefficient     The coefficient, or 'QInv'.
     */
    public PrivateKey(final BigInteger modulus, final BigInteger publicExponent, final BigInteger privateExponent,
            final BigInteger prime1, final BigInteger prime2, final BigInteger primeExponent1,
            final BigInteger primeExponent2, final BigInteger coefficient) {
        this.modulus = modulus;
        this.publicExponent = publicExponent;
        this.privateExponent = privateExponent;
        this.prime1 = prime1;
        this.prime2 = prime2;
        this.primeExponent1 = primeExponent1;
        this.primeExponent2 = primeExponent2;
        this.coefficient = coefficient;
    }

    /**
     * Get the modulus.
     *
     * @return The modulus.
     */
    public BigInteger modulus() {
        return this.modulus;
    }

    /**
     * Get the public exponent.
     *
     * @return The public exponent.
     */
    public BigInteger publicExponent() {
        return this.publicExponent;
    }

    /**
     * Get the private exponent.
     *
     * @return The private exponent.
     */
    public BigInteger privateExponent() {
        return this.privateExponent;
    }

    /**
     * Get the first prime, or 'P'.
     *
     * @return The first prime.
     */
    public BigInteger prime1() {
        return this.prime1;
    }

    /**
     * Get the second prime, or 'Q'.
     *
     * @return The second prime.
     */
    public BigInteger prime2() {
        return this.prime2;
    }

    /**
     * Get the first prime exponent, or 'DP'.
     *
     * @return The first prime exponent.
     */
    public BigInteger primeExponent1() {
        return this.primeExponent1;
    }

    /**
     * Get the second prime exponent, or 'DQ'.
     *
     * @return The second prime exponent.
     */
    public BigInteger primeExponent2() {
        return this.primeExponent2;
    }

    /**
     * Get the coefficient, or 'QInv'.
     *
     * @return The coefficient.
     */
    public BigInteger coefficient() {
        return this.coefficient;
    }

    /**
     * Get the size of this key in bits.
     *
     * @return The key size.
     */
    public int size() {
        return this.modulus().bitLength();
    }

    /**
     * Get the generic Bouncy Castle asymmetric key parameters.
     *
     * @return The generic Bouncy Castle asymmetric key parameters.
     */
    public AsymmetricKeyParameter bcKeyParameters() {
        return this.bcPrivateKeyParameters();
    }

    /**
     * Get the public key counterpart for this private key.
     *
     * @return The public key.
     */
    public PublicKey publicKey() {
        return new PublicKey(this.modulus(), this.publicExponent());
    }

    /**
     * Get the Bouncy Castle RSA private key parameters.
     *
     * @return The Bouncy Castle RSA private key parameters.
     */
    public RSAPrivateCrtKeyParameters bcPrivateKeyParameters() {
        return new RSAPrivateCrtKeyParameters(this.modulus(), this.publicExponent(), this.privateExponent(),
                this.prime1(), this.prime2(), this.primeExponent1(), this.primeExponent2(), this.coefficient());
    }

    /**
     * Get the Bouncy Castle RSA private key.
     *
     * @return The BouncyCastle RSA private key.
     */
    public RSAPrivateKey bcPrivateKey() {
        return new RSAPrivateKey(this.modulus(), this.publicExponent(), this.privateExponent(), this.prime1(),
                this.prime2(), this.primeExponent1(), this.primeExponent2(), this.coefficient());
    }

    /**
     * Get the Bouncy Castle private key information.
     *
     * @return The Bouncy Castle private key information.
     */
    public PrivateKeyInfo bcPrivateKeyInfo() {
        return this.bcPrivateKeyInfo(new PrivateKeyInformationFactory());
    }

    /**
     * Get the Bouncy Castle private key information.
     *
     * @param factory The private key information factory to use.
     *
     * @return The Bouncy Castle private key information.
     */
    public PrivateKeyInfo bcPrivateKeyInfo(final PrivateKeyInformationFactoryInterface factory) {
        PrivateKeyInfo keyInfo;
        try {
            keyInfo = factory.create(this.bcPrivateKeyParameters());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return keyInfo;
    }

    /**
     * Get the JCE private key.
     *
     * @return The JCE private key.
     */
    public java.security.PrivateKey jcePrivateKey() {
        JcaPEMKeyConverter keyConverter = new JcaPEMKeyConverter();
        keyConverter.setProvider(new BouncyCastleProvider());

        return this.jcePrivateKey(keyConverter);
    }

    /**
     * Get the JCE private key.
     *
     * @param keyConverter The key converter to use.
     *
     * @return The JCE private key.
     */
    public java.security.PrivateKey jcePrivateKey(final JcaPEMKeyConverter keyConverter) {
        java.security.PrivateKey jcePrivateKey;
        try {
            jcePrivateKey = keyConverter.getPrivateKey(this.bcPrivateKeyInfo());
        } catch (PEMException e) {
            throw new RuntimeException(e);
        }

        return jcePrivateKey;
    }

    /**
     * Get this key as a PEM formatted string.
     *
     * @return The PEM formatted key.
     */
    public String toPem() {
        return this.toPem(new StringWriterFactory(), new PemWriterFactory());
    }

    /**
     * Get this key as a PEM formatted string.
     *
     * @param password A password to encrypt the PEM data with.
     *
     * @return The PEM formatted key.
     */
    public String toPem(final String password) {
        JcePEMEncryptorBuilder encryptorBuilder = new JcePEMEncryptorBuilder("DES-EDE3-CBC");
        encryptorBuilder.setProvider(new BouncyCastleProvider());

        return this.toPem(password, encryptorBuilder, new StringWriterFactory(), new PemWriterFactory());
    }

    /**
     * Get this key as a PEM formatted string.
     *
     * @param stringWriterFactory The string writer factory to use.
     * @param pemWriterFactory    The PEM writer factory to use.
     *
     * @return The PEM formatted key.
     */
    public String toPem(final StringWriterFactoryInterface stringWriterFactory,
            final PemWriterFactoryInterface pemWriterFactory) {
        return this.toPem(null, null, stringWriterFactory, pemWriterFactory);
    }

    /**
     * Get this key as an encrypted PEM formatted string.
     *
     * @param password            A password to encrypt the PEM data with.
     * @param encryptorBuilder    The encryptor builder to use.
     * @param stringWriterFactory The string writer factory to use.
     * @param pemWriterFactory    The PEM writer factory to use.
     *
     * @return The PEM formatted key.
     */
    public String toPem(final String password, final JcePEMEncryptorBuilder encryptorBuilder,
            final StringWriterFactoryInterface stringWriterFactory,
            final PemWriterFactoryInterface pemWriterFactory) {
        PEMEncryptor encryptor = null;
        if (null != password) {
            encryptor = encryptorBuilder.build(password.toCharArray());
        }

        StringWriter stringWriter = stringWriterFactory.create();
        PEMWriter pemWriter = pemWriterFactory.create(stringWriter);

        IOException error = null;
        try {
            if (null == encryptor) {
                pemWriter.writeObject(this.bcPrivateKeyInfo());
            } else {
                pemWriter.writeObject(this.bcPrivateKeyInfo(), encryptor);
            }
        } catch (IOException e) {
            error = e;
        }

        try {
            pemWriter.close();
        } catch (IOException e) {
            if (null == error) {
                error = e;
            }
        }

        try {
            stringWriter.close();
        } catch (IOException e) {
            if (null == error) {
                error = e;
            }
        }

        if (null != error) {
            throw new RuntimeException(error);
        }

        return stringWriter.toString();
    }

    /**
     * Get this key as a PEM formatted string.
     *
     * @return The PEM formatted key.
     */
    @Override
    public String toString() {
        return this.toPem();
    }

    private BigInteger modulus;
    private BigInteger publicExponent;
    private BigInteger privateExponent;
    private BigInteger prime1;
    private BigInteger prime2;
    private BigInteger primeExponent1;
    private BigInteger primeExponent2;
    private BigInteger coefficient;
}