org.xdi.oxauth.model.crypto.signature.ECDSAKeyFactory.java Source code

Java tutorial

Introduction

Here is the source code for org.xdi.oxauth.model.crypto.signature.ECDSAKeyFactory.java

Source

/*
 * oxAuth is available under the MIT License (2008). See http://opensource.org/licenses/MIT for full text.
 *
 * Copyright (c) 2014, Gluu
 */

package org.xdi.oxauth.model.crypto.signature;

import org.apache.commons.lang.StringUtils;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.ECNamedCurveTable;
import org.bouncycastle.jce.spec.ECParameterSpec;
import org.bouncycastle.x509.X509V1CertificateGenerator;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import org.xdi.oxauth.model.crypto.Certificate;
import org.xdi.oxauth.model.crypto.KeyFactory;

import javax.security.auth.x500.X500Principal;
import java.math.BigInteger;
import java.security.*;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Random;

/**
 * Factory to create asymmetric Public and Private Keys for the Elliptic Curve Digital Signature Algorithm (ECDSA)
 *
 * @author Javier Rojas Blum
 * @version June 15, 2016
 */
public class ECDSAKeyFactory extends KeyFactory<ECDSAPrivateKey, ECDSAPublicKey> {

    private SignatureAlgorithm signatureAlgorithm;
    private KeyPair keyPair;

    private ECDSAPrivateKey ecdsaPrivateKey;
    private ECDSAPublicKey ecdsaPublicKey;
    private Certificate certificate;

    public ECDSAKeyFactory(SignatureAlgorithm signatureAlgorithm, String dnName) throws InvalidParameterException,
            NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException,
            SignatureException, InvalidKeyException, CertificateEncodingException {
        if (signatureAlgorithm == null) {
            throw new InvalidParameterException("The signature algorithm cannot be null");
        }

        this.signatureAlgorithm = signatureAlgorithm;

        ECParameterSpec ecSpec = ECNamedCurveTable.getParameterSpec(signatureAlgorithm.getCurve().getName());

        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("ECDSA", "BC");
        keyGen.initialize(ecSpec, new SecureRandom());

        this.keyPair = keyGen.generateKeyPair();
        BCECPrivateKey privateKeySpec = (BCECPrivateKey) keyPair.getPrivate();
        BCECPublicKey publicKeySpec = (BCECPublicKey) keyPair.getPublic();

        BigInteger x = publicKeySpec.getQ().getX().toBigInteger();
        BigInteger y = publicKeySpec.getQ().getY().toBigInteger();
        BigInteger d = privateKeySpec.getD();

        this.ecdsaPrivateKey = new ECDSAPrivateKey(d);
        this.ecdsaPublicKey = new ECDSAPublicKey(signatureAlgorithm, x, y);

        if (StringUtils.isNotBlank(dnName)) {
            // Create certificate
            GregorianCalendar startDate = new GregorianCalendar(); // time from which certificate is valid
            GregorianCalendar expiryDate = new GregorianCalendar(); // time after which certificate is not valid
            expiryDate.add(Calendar.YEAR, 1);
            BigInteger serialNumber = new BigInteger(1024, new Random()); // serial number for certificate

            X509V1CertificateGenerator certGen = new X509V1CertificateGenerator();
            X500Principal principal = new X500Principal(dnName);

            certGen.setSerialNumber(serialNumber);
            certGen.setIssuerDN(principal);
            certGen.setNotBefore(startDate.getTime());
            certGen.setNotAfter(expiryDate.getTime());
            certGen.setSubjectDN(principal); // note: same as issuer
            certGen.setPublicKey(keyPair.getPublic());
            certGen.setSignatureAlgorithm("SHA256WITHECDSA");

            X509Certificate x509Certificate = certGen.generate(privateKeySpec, "BC");
            this.certificate = new Certificate(signatureAlgorithm, x509Certificate);
        }
    }

    public Certificate generateV3Certificate(Date startDate, Date expirationDate, String dnName)
            throws CertificateEncodingException, InvalidKeyException, IllegalStateException,
            NoSuchProviderException, NoSuchAlgorithmException, SignatureException {
        // Create certificate
        BigInteger serialNumber = new BigInteger(1024, new Random()); // serial number for certificate

        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
        X500Principal principal = new X500Principal(dnName);

        certGen.setSerialNumber(serialNumber);
        certGen.setIssuerDN(principal);
        certGen.setNotBefore(startDate);
        certGen.setNotAfter(expirationDate);
        certGen.setSubjectDN(principal); // note: same as issuer
        certGen.setPublicKey(keyPair.getPublic());
        certGen.setSignatureAlgorithm(signatureAlgorithm.getAlgorithm());

        X509Certificate x509Certificate = certGen.generate(keyPair.getPrivate(), "BC");
        return new Certificate(signatureAlgorithm, x509Certificate);
    }

    @Override
    public ECDSAPrivateKey getPrivateKey() {
        return ecdsaPrivateKey;
    }

    @Override
    public ECDSAPublicKey getPublicKey() {
        return ecdsaPublicKey;
    }

    @Override
    public Certificate getCertificate() {
        return certificate;
    }
}