BouncyCastle签名认证机制

BouncyCastle签名认证CA机制


    package com.ideal.mdm.cert.service;

    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.math.BigInteger;
    import java.security.InvalidKeyException;
    import java.security.KeyFactory;
    import java.security.KeyPair;
    import java.security.NoSuchAlgorithmException;
    import java.security.NoSuchProviderException;
    import java.security.PrivateKey;
    import java.security.PublicKey;
    import java.security.Security;
    import java.security.SignatureException;
    import java.security.cert.CertStoreException;
    import java.security.cert.CertificateException;
    import java.security.cert.CertificateFactory;
    import java.security.cert.X509Certificate;
    import java.security.spec.InvalidKeySpecException;
    import java.security.spec.RSAPublicKeySpec;
    import java.util.Calendar;
    import java.util.Date;
    import java.util.GregorianCalendar;
    import java.util.Random;

    import javax.security.auth.x500.X500Principal;

    import org.apache.log4j.Logger;
    import org.bouncycastle.asn1.ASN1EncodableVector;
    import org.bouncycastle.asn1.ASN1Sequence;
    import org.bouncycastle.asn1.DEROctetString;
    import org.bouncycastle.asn1.DERSequence;
    import org.bouncycastle.asn1.x500.X500Name;
    import org.bouncycastle.asn1.x500.X500NameStyle;
    import org.bouncycastle.asn1.x509.BasicConstraints;
    import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
    import org.bouncycastle.asn1.x509.Extension;
    import org.bouncycastle.asn1.x509.GeneralName;
    import org.bouncycastle.asn1.x509.KeyPurposeId;
    import org.bouncycastle.asn1.x509.KeyUsage;
    import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
    import org.bouncycastle.asn1.x509.X509Extension;
    import org.bouncycastle.cert.X509CertificateHolder;
    import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
    import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
    import org.bouncycastle.crypto.params.RSAKeyParameters;
    import org.bouncycastle.crypto.util.PublicKeyFactory;
    import org.bouncycastle.openssl.PEMReader;
    import org.bouncycastle.operator.ContentSigner;
    import org.bouncycastle.operator.OperatorCreationException;
    import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
    import org.bouncycastle.pkcs.PKCS10CertificationRequest;
    import org.jscep.client.ClientException;
    import org.jscep.transaction.FailInfo;
    import org.jscep.transaction.OperationFailureException;
    import org.jscep.transaction.TransactionException;

    import com.ideal.mdm.cert.util.WinBCStyle;

    import sun.misc.BASE64Decoder;


    public class SCEPCertService {
        protected static final Logger logger = Logger.getLogger(SCEPCertService.class);
        private static PrivateKey priKey;
        private static PublicKey pubKey;
        private static X509Certificate ca;
        private static X500Name issuer;
        private static X500Name pollName;
        private static BigInteger caSerial;

        public static X509Certificate mainSignCSRProcedure(String b64DerCsr)
            throws NoSuchAlgorithmException, SignatureException,
            InvalidKeyException, NoSuchProviderException, ClientException,
            OperatorCreationException, TransactionException,
            CertificateException, CertStoreException, IOException, InvalidKeySpecException {

            init();
            BASE64Decoder decoder = new BASE64Decoder();
            byte[] derCsr;
            PublicKey csrPubKey;
            derCsr=decoder.decodeBuffer(b64DerCsr);
            csrPubKey = geneneratePublicKey(derCsr);
            X509Certificate issued=doEnrol(csrPubKey);
            return issued;

            //PemReader pemReader = null;
            /*try {
                FileReader fileReader = new FileReader(csrPath);
                pemReader = new PemReader(fileReader);
            } catch (FileNotFoundException e1) {
                e1.printStackTrace();
                logger.debug(e1.getMessage());
            }*/

            /*PKCS10CertificationRequest csr = null;
            try {
                csr = new PKCS10CertificationRequest(pemReader.readPemObject()
                        .getContent());
            } catch (IOException e) {
                e.printStackTrace();
                logger.debug(e.getMessage());
            }*/


        }
        protected static X509Certificate doEnrol(PublicKey csrPubKey) throws OperationFailureException {
            try {

                //X500Name origin_subject = X500Name.getInstance(csr.getSubject());
                /*if (subject.equals(pollName)) {
                return Collections.emptyList();
                }*/
                //logger.debug(origin_subject.toString());
                //new X500Name();
    //          PrintableString ps=new PrintableString("");
                //X500Principal
                X500Name new_subject=new X500Name(WinBCStyle.INSTANCE,"CN=IdealMobile01");
                //new_subject instanceof PrintableString;
                //new_subject.getRDNs()[0].
                //PublicKey pubKey = CertificationRequestUtils.getPublicKey(csr);

                X509Certificate issued = generateCertificate(csrPubKey, new_subject, issuer,
                    getSerial());
                return issued;
            } catch (Exception e) {
                logger.debug(e.getMessage());
                throw new OperationFailureException(FailInfo.badRequest);

            }
        }

        private static X509Certificate generateCertificate(PublicKey pubKey,
            X500Name subject, X500Name issuer, BigInteger serial)
            throws Exception {
            Calendar cal = GregorianCalendar.getInstance();
            cal.add(Calendar.YEAR, -1);
            Date notBefore = cal.getTime();

            cal.add(Calendar.YEAR, 2);
            Date notAfter = cal.getTime();

            JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
                issuer, serial, notBefore, notAfter, subject, pubKey);
            builder.addExtension(X509Extension.basicConstraints, true,
                new BasicConstraints(false));

    //      ExtendedKeyUsage anyExtendedKeyUsage = new ExtendedKeyUsage(KeyPurposeId.anyExtendedKeyUsage);
    //      X509Extension anyExtendedKeyUsageExtension = new X509Extension(false, new DEROctetString(anyExtendedKeyUsage));
    //      builder.addExtension(X509Extension.extendedKeyUsage, true, anyExtendedKeyUsageExtension.getParsedValue());

        ASN1EncodableVector asn1ExtKeyUsage = new ASN1EncodableVector();
    //      asn1ExtKeyUsage.add(KeyPurposeId.anyExtendedKeyUsage); // 任何用途
    //      asn1ExtKeyUsage.add(KeyPurposeId.id_kp_serverAuth); // SSL的服务器认证
        asn1ExtKeyUsage.add(KeyPurposeId.id_kp_clientAuth); // SSL的客户端认证
    //      asn1ExtKeyUsage.add(KeyPurposeId.id_kp_codeSigning); // 代码签名
    //      asn1ExtKeyUsage.add(KeyPurposeId.id_kp_codeSigning); // 代码签名
    //      asn1ExtKeyUsage.add(KeyPurposeId.id_kp_ipsecEndSystem); //
    //      asn1ExtKeyUsage.add(KeyPurposeId.id_kp_ipsecTunnel); //
    //      asn1ExtKeyUsage.add(KeyPurposeId.id_kp_ipsecUser); //
    //      asn1ExtKeyUsage.add(KeyPurposeId.id_kp_timeStamping); // 时间戳 认证
    //      asn1ExtKeyUsage.add(KeyPurposeId.id_kp_OCSPSigning); // ocsp证书认证
    //      asn1ExtKeyUsage.add(KeyPurposeId.id_kp_smartcardlogon);
    //      asn1ExtKeyUsage.add(new GeneralName(GeneralName.dNSName,"ejbca.linyiheng.cn"));

        ExtendedKeyUsage extendedKeyUsage = new ExtendedKeyUsage(new DERSequence(asn1ExtKeyUsage));
        builder.addExtension(Extension.extendedKeyUsage, true, extendedKeyUsage);
        //builder.addExtension(Extension.subjectAlternativeName, true, arg2)

        KeyUsage keyUsage= new KeyUsage(KeyUsage.digitalSignature);
        X509Extension keyUsageExtension = new X509Extension(true, new DEROctetString(keyUsage));
        builder.addExtension(X509Extension.keyUsage, true, keyUsageExtension.getParsedValue());
        ContentSigner signer;
        try {
            signer = new JcaContentSignerBuilder("SHA1withRSA").build(priKey);
        } catch (OperatorCreationException e) {
            logger.debug(e.getMessage());
            throw new Exception(e);
        }
        X509CertificateHolder holder = builder.build(signer);
        X509Certificate cert = new JcaX509CertificateConverter()
                .getCertificate(holder);
        //savePEMFile("/root/certificate/client.crt", cert);
        logger.debug("Cert's issuer DN is: "+cert);
        return cert;
    }

    //  private static void savePEMFile(String path, Object obj) throws IOException {
    //      FileWriter fw = new FileWriter(path);
    //      PEMWriter writer = new PEMWriter(fw);
    //      writer.writeObject(obj);
    //      writer.close();
    //  }

    public static void init() {
        try {
            ca = loadLocalCertificate();

            //BouncyCastleHelpers.toX500Name(ca.getSubjectX500Principal());
            //new X500Name((ASN1Sequence) ca.getIssuerDN());
            //new X500Name();
            //new X500Name(ca.getSubjectX500Principal().RFC1779);
    //          logger.debug("CA's issuer is :"+ ca.getSubjectX500Principal().getName());
    //          logger.debug("CA's issuer is :"+ ca.getSubjectX500Principal().getName(X500Principal.RFC1779));
    //          logger.debug("CA's issuer is :"+ ca.getSubjectX500Principal().getName(X500Principal.RFC2253));
    //          logger.debug("CA's issuer is :"+ ca.getSubjectX500Principal().getName(X500Principal.CANONICAL));

            issuer = new X500Name(WinBCStyle.INSTANCE,"C=CN,ST=SH,L=SH,O=Ideal,OU=Ideal,CN=host.linyiheng.cn,[email protected]");
            //pollName = new X500Name("CN=Poll2");
            caSerial = BigInteger.TEN;
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    new SCEPCertService().getClass().getResourceAsStream("/ca.key")));
            PEMReader localPEMReader=new PEMReader(br);
    //          PEMReader localPEMReader = new PEMReader(br, new PasswordFinder() {
    //
    //              public char[] getPassword() {
    //                  return "1111".toCharArray();
    //              }
    //
    //          });
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
            priKey = ((KeyPair) localPEMReader.readObject()).getPrivate();
            localPEMReader.close();
            br.close();
            pubKey = ca.getPublicKey();
        } catch (IOException e) {
            logger.debug(e.getMessage());
            e.printStackTrace();
        }
    }

    public static X509Certificate loadLocalCertificate() {
        try {

            InputStream ica = new SCEPCertService().getClass().getResourceAsStream("/ca.crt");
            CertificateFactory certFactory = CertificateFactory
                    .getInstance("X.509");
            ca = (X509Certificate) certFactory.generateCertificate(ica);
        } catch (Exception e) {
            logger.debug(e.getMessage());
            e.printStackTrace();
        }
        return ca;
    }

    private static BigInteger getSerial() {
        Random rnd = new Random();
        return BigInteger.valueOf(Math.abs(rnd.nextLong()) + 1);
    }

    public static PublicKey geneneratePublicKey(byte[] key) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException { 
        PKCS10CertificationRequest pkcs10CertReq=new PKCS10CertificationRequest(key);
        SubjectPublicKeyInfo pkInfo = pkcs10CertReq.getSubjectPublicKeyInfo();
        RSAKeyParameters rsa = (RSAKeyParameters) PublicKeyFactory.createKey(pkInfo);
        RSAPublicKeySpec rsaSpec = new RSAPublicKeySpec(rsa.getModulus(), rsa.getExponent());
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");  
        return keyFactory.generatePublic(rsaSpec);  
    }   


}

BC Style

通过修改默认的BCStyle可以修改subject与issuer的名称类型。具体可以通过grepcode了解其中源码。

你可能感兴趣的:(JAVA加密)