USBKEY 전체 해석 - 인증서 가 져 오기 (java)

16585 단어 CA 총동원
인터넷 자 료 는 JAVA 가 하드웨어 USB 키 를 조작 하 는 사례 가 비교적 적 고 본 편의 사용 은 주로 2 가지 기능 을 실현 한다.
1    자바, USBKEY 에 인증서 가 져 오기
2    자바 USBKEY 인증서 서명 호출
USBKEY 의 낯 선 친구 에 게 참고 하 세 요:https://blog.csdn.net/liujoi/article/details/106150546
이 편 은 bcpkix - jdk15on - 160. jar, bcprov - ext - jdk15on - 160. jar 를 사용 해 야 합 니 다. 전체 원본 은 첨부 파일 을 보십시오.
package org.liuy.pkcs11;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.math.BigInteger;
import java.security.InvalidKeyException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.Provider;
import java.security.SecureRandom;
import java.security.Security;
import java.security.Signature;
import java.security.SignatureException;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
import javax.security.auth.x500.X500Principal;
import org.bouncycastle.asn1.x509.BasicConstraints;
import org.bouncycastle.asn1.x509.ExtendedKeyUsage;
import org.bouncycastle.asn1.x509.GeneralName;
import org.bouncycastle.asn1.x509.GeneralNames;
import org.bouncycastle.asn1.x509.KeyPurposeId;
import org.bouncycastle.asn1.x509.KeyUsage;
import org.bouncycastle.asn1.x509.X509Extensions;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.x509.X509V3CertificateGenerator;
import sun.misc.BASE64Encoder;
import sun.security.pkcs11.SunPKCS11;
import sun.security.pkcs11.wrapper.CK_ATTRIBUTE;
import sun.security.pkcs11.wrapper.CK_INFO;
import sun.security.pkcs11.wrapper.CK_SESSION_INFO;
import sun.security.pkcs11.wrapper.CK_SLOT_INFO;
import sun.security.pkcs11.wrapper.CK_TOKEN_INFO;
import sun.security.pkcs11.wrapper.PKCS11;
import sun.security.pkcs11.wrapper.PKCS11Constants;
import sun.security.pkcs11.wrapper.PKCS11Exception;

/**
 *   PKCS11    USBKEY:    、  、           
 * 
 * @author liuy
 *
 */
public class Pkcs11Util {
        
    protected PKCS11 myPKCS11Module_;
      protected long token_ = -1L;
    
    /**
     *       ,      
     * @param libPath    pkcs11    :windows linux   
     * @throws IOException
     * @throws PKCS11Exception
     */
    public Pkcs11Util(String libPath) throws IOException, PKCS11Exception
    {
        myPKCS11Module_ = PKCS11.getInstance(libPath, "C_GetFunctionList", null, false); 
    }
    
    /**
     *   Cryptoki     
     * @throws PKCS11Exception
     */
    public CK_INFO getInfo()  throws PKCS11Exception
    {
            CK_INFO moduleInfo = myPKCS11Module_.C_GetInfo();
            return moduleInfo;
     }
    
    
    /**
     *       
     * @return
     * @throws PKCS11Exception
     */
    public List getSlotInfo() throws PKCS11Exception
   {
          List  list= new ArrayList();
          long[] slotIDs = myPKCS11Module_.C_GetSlotList(false);
          for (int i=0; i < slotIDs.length; i++) {
            CK_SLOT_INFO slotInfo = myPKCS11Module_.C_GetSlotInfo(slotIDs[i]);
            list.add(slotInfo);
          }
          return list;
    }
    
     /**
      *       
      * @return
      * @throws PKCS11Exception
      */
     public List  getTokenInfo() throws PKCS11Exception
     {
        List  list= new ArrayList(); 
        long[] tokenIDs = myPKCS11Module_.C_GetSlotList(true);
        for (int i=0; i < tokenIDs.length; i++) {
          CK_TOKEN_INFO tokenInfo = myPKCS11Module_.C_GetTokenInfo(tokenIDs[i]);
          list.add(tokenInfo);
          if (token_ == -1L) {
              token_ = tokenIDs[i];
            }
        }
        return list;
     }
    
    /**
     * PKCS11     
     * @param cert
     * @param label
     * @param id
     * @return
     * @throws PKCS11Exception 
     * 
     * @throws CertificateEncodingException 
     */
    public void uploadCertificate(X509Certificate cert, String label, String id) throws PKCS11Exception, CertificateEncodingException {
        long session_ = myPKCS11Module_.C_OpenSession(token_,PKCS11Constants.CKF_RW_SESSION | PKCS11Constants.CKF_SERIAL_SESSION, null, null);
        CK_SESSION_INFO sessionInfo = myPKCS11Module_.C_GetSessionInfo(session_);
        System.out.println(sessionInfo);
        
        CK_ATTRIBUTE[] certificate = new CK_ATTRIBUTE[9];
//        certificate[0] = new CK_ATTRIBUTE(PKCS11Constants.CKA_CLASS, PKCS11Constants.CKO_CERTIFICATE);
//        certificate[1] = new CK_ATTRIBUTE(PKCS11Constants.CKA_TOKEN, true);
//        certificate[2] = new CK_ATTRIBUTE(PKCS11Constants.CKA_PRIVATE, false);
//        certificate[3] = new CK_ATTRIBUTE(PKCS11Constants.CKA_LABEL, label.toCharArray());
//        certificate[4] = new CK_ATTRIBUTE(PKCS11Constants.CKA_SUBJECT, cert.getSubjectX500Principal().getEncoded());
//        certificate[5] = new CK_ATTRIBUTE(PKCS11Constants.CKA_ID, StringUtil.hexStringToByte(id));
//        certificate[6] = new CK_ATTRIBUTE(PKCS11Constants.CKA_ISSUER, cert.getIssuerX500Principal().getEncoded());
//        certificate[7] = new CK_ATTRIBUTE(PKCS11Constants.CKA_SERIAL_NUMBER, cert.getSerialNumber().toByteArray());
//        certificate[8] = new CK_ATTRIBUTE(PKCS11Constants.CKA_VALUE, cert.getEncoded());
//        myPKCS11Module_.C_CreateObject(session_, certificate);
//        myPKCS11Module_.C_CloseSession(token_);

    }
    
    /**
     *     
     * @param cfgPath          
     * @param pin       USBKEY  
     * @throws InvalidKeyException
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws NoSuchProviderException
     * @throws SignatureException
     * @throws IllegalStateException
     * @throws IOException
     */
    public void  importCert(String  cfgPath,String pin) throws InvalidKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, IllegalStateException, IOException
    {
        Provider p = new SunPKCS11(cfgPath);
        importCert(p,pin);
    }
    
    
    /***
     *  
     *     ,         
     * @param cfgPath          
     * @param pin       USBKEY  
     * @throws InvalidKeyException
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws NoSuchProviderException
     * @throws SignatureException
     * @throws IllegalStateException
     * @throws IOException
     */
    public void  importCert(ByteArrayInputStream confStream,String pin) throws InvalidKeyException, KeyStoreException, NoSuchAlgorithmException, CertificateException, NoSuchProviderException, SignatureException, IllegalStateException, IOException
    {
        Provider p = new SunPKCS11(confStream);
        importCert(p,pin);
    }
    
    
    /**
     *   sunPKCS11    
     * @param cfgPath          
     * @param pin       USBKEY  
     * @throws KeyStoreException 
     * @throws IOException 
     * @throws CertificateException 
     * @throws NoSuchAlgorithmException 
     * @throws IllegalStateException 
     * @throws SignatureException 
     * @throws NoSuchProviderException 
     * @throws InvalidKeyException 
     */
    private void  importCert(Provider p,String pin) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, InvalidKeyException, NoSuchProviderException, SignatureException, IllegalStateException
    {
         if (-1 == Security.addProvider(p)) {
             throw new RuntimeException("could not add security provider");
         }

         //pin U    
         char[] upin = pin.toCharArray();
         KeyStore ks = KeyStore.getInstance("PKCS11", p);
         ks.load(null, upin);

         //    ,    PKCS10  
         SecureRandom sr = new SecureRandom();
         KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA", p);
         keyGen.initialize(2048, sr);
         KeyPair keyPair = keyGen.generateKeyPair();
         PrivateKey pk = keyPair.getPrivate();

         X509Certificate[] chain = generateV3Certificate(keyPair);
         //alias           ,              
         String alias=String.valueOf(System.currentTimeMillis());
         ks.setKeyEntry(alias, pk,null, chain);
         ks.store(null);
        
         System.out.println("OK");
    }
    
    /**
     * USBKEY  
     * @param cfgPath        
     * @param data         
     * @param pin      UBKEY  
     * @throws KeyStoreException
     * @throws NoSuchAlgorithmException
     * @throws CertificateException
     * @throws IOException
     * @throws UnrecoverableKeyException
     * @throws InvalidKeyException
     * @throws SignatureException
     */ 
    public void  sign(String  cfgPath,String data,String pin) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, IOException, UnrecoverableKeyException, InvalidKeyException, SignatureException
    {
        //CSP
//        BouncyCastleProvider providerBC = new BouncyCastleProvider();
//        Security.addProvider(providerBC);
//        SunMSCAPI providerMSCAPI = new SunMSCAPI();
//        Security.addProvider(providerMSCAPI);
//        KeyStore ks = KeyStore.getInstance("Windows-MY","SunMSCAPI");
//        ks.load(null, null);
        
        //P11
        SunPKCS11 providerMSCAPI = new SunPKCS11(cfgPath);
        Provider a = providerMSCAPI;
        Security.addProvider(a);
        
        KeyStore ks = KeyStore.getInstance("PKCS11");
        ks.load(null, pin.toCharArray());
        
        Enumeration aliases = ks.aliases();
        while (aliases.hasMoreElements()) 
        {
            String alias = aliases.nextElement();
            System.out.println("alias:" + alias+":");
    
            X509Certificate x509 = (X509Certificate) ks.getCertificate(alias);
            PrivateKey pk=(PrivateKey)ks.getKey(alias, null);
            byte[]  pkBy=pk.getEncoded();
            
            //     
            Signature signature = Signature.getInstance(x509.getSigAlgName());
            signature.initSign(pk);
            signature.update(data.getBytes());
            byte[] sign=signature.sign();
            
            System.out.println(Base64.toBase64String(sign));
        }
    }
    
    /**
     *     
     * @param pair
     * @return
     * @throws InvalidKeyException
     * @throws NoSuchProviderException
     * @throws SignatureException
     * @throws CertificateEncodingException
     * @throws IllegalStateException
     * @throws NoSuchAlgorithmException
     */
    public  X509Certificate[] generateV3Certificate(KeyPair pair) throws InvalidKeyException, NoSuchProviderException, SignatureException, CertificateEncodingException, IllegalStateException, NoSuchAlgorithmException {
        
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        X509V3CertificateGenerator certGen = new X509V3CertificateGenerator();
        certGen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis()));
        certGen.setIssuerDN(new X500Principal("CN=Test Certificate"));
        certGen.setNotBefore(new Date(System.currentTimeMillis() - 10000));
        certGen.setNotAfter(new Date(System.currentTimeMillis() + 10000));
        certGen.setSubjectDN(new X500Principal("CN=Test Certificate"));
        certGen.setPublicKey(pair.getPublic());
        certGen.setSignatureAlgorithm("SHA256WithRSA");

        certGen.addExtension(X509Extensions.BasicConstraints, true, new BasicConstraints(false));
        certGen.addExtension(X509Extensions.KeyUsage, true, new KeyUsage(KeyUsage.digitalSignature | KeyUsage.keyEncipherment));
        certGen.addExtension(X509Extensions.ExtendedKeyUsage, true, new ExtendedKeyUsage(KeyPurposeId.id_kp_serverAuth));

        certGen.addExtension(X509Extensions.SubjectAlternativeName, false, new GeneralNames(new GeneralName(GeneralName.rfc822Name, "[email protected]")));

        X509Certificate[] chain = new X509Certificate[1];
        chain[0] = certGen.generate(pair.getPrivate());

        return chain;
    }
    
    public static void main(String[] args) throws Exception
    {        
       String realPath = Pkcs11Util.class.getClassLoader().getResource("").getFile();
       java.io.File file = new java.io.File(realPath);
       realPath = file.getCanonicalPath();
       String libPath=realPath+"/ShuttleCsp11_3003_15.dll";
        
        Pkcs11Util  p11=new Pkcs11Util(libPath);
        CK_INFO ck_info=p11.getInfo();
        System.out.println("     :"+ck_info.cryptokiVersion);
        System.out.println("      :"+String.valueOf(ck_info.manufacturerID));
        System.out.println();
        
        List slotList=p11.getSlotInfo();
        for(int i=0; i < slotList.size(); i++)
        {
            CK_SLOT_INFO slot_info=slotList.get(i);
            System.out.println("    :"+String.valueOf(slot_info.slotDescription)); 
            System.out.println("    :"+String.valueOf(slot_info.manufacturerID)); 
            System.out.println("    :"+slot_info.flags);
            System.out.println("    :"+slot_info.hardwareVersion);
            System.out.println("    :"+slot_info.hardwareVersion);
            System.out.println();
        }
        
        List tokenList=p11.getTokenInfo();
        for(int i=0; i < tokenList.size(); i++)
        {
            CK_TOKEN_INFO token_info=tokenList.get(i);
            System.out.println("    :"+String.valueOf(token_info.label)); 
            System.out.println("    :"+String.valueOf(token_info.manufacturerID)); 
            System.out.println("    :"+String.valueOf(token_info.model));
            System.out.println("     :"+String.valueOf(token_info.serialNumber));
            System.out.println("    :"+token_info.flags);
            System.out.println("     :"+token_info.ulMaxSessionCount);
            System.out.println("     :"+token_info.ulSessionCount);
            System.out.println("PIN    :"+token_info.ulMaxPinLen);
            System.out.println("PIN    :"+token_info.ulMinPinLen);
            System.out.println("PIN    :"+token_info.ulMinPinLen);
            System.out.println("       :"+token_info.ulTotalPublicMemory);
            System.out.println("        :"+token_info.ulFreePublicMemory);
            System.out.println("       :"+token_info.ulTotalPrivateMemory);
            System.out.println("        :"+token_info.ulFreePrivateMemory);
            System.out.println("    :"+token_info.hardwareVersion);
            System.out.println();
        }
        
            //  KEY   :    epass3003     
          //    :https://detail.tmall.com/item.htm?id=43722580737
          StringBuffer setP11Conf=new StringBuffer();
          setP11Conf.append("name=epass3003 
");           // linux, so           setP11Conf.append("library="+libPath+"
");           //           setP11Conf.append("slot=1
");           setP11Conf.append("attributes(generate, *, *) = { CKA_TOKEN = true }  
");           setP11Conf.append("attributes(generate, CKO_CERTIFICATE, *) = { CKA_PRIVATE = false }  
");           setP11Conf.append("attributes(generate, CKO_PUBLIC_KEY, *) = { CKA_PRIVATE = false }  
");                   byte[] pkcs11ConfigBytes = setP11Conf.toString().getBytes();           ByteArrayInputStream confStream = new ByteArrayInputStream(pkcs11ConfigBytes); //          p11.importCert(confStream, "123456");                      String cfgPath=realPath+"/epass3003.cfg";           p11.sign(cfgPath, "123", "123456");     } }

실제 프로젝트 에서 u 방패 생산 PKCS 10 은 CA 회사 에 요청 하고 CA 회사 에서 인증 서 를 발급 하여 가 져 옵 니 다.사용 할 때 alias 생산 P10 을 기록 한 후, alias 에 따라 인증 서 를 가 져 올 수 있 습 니 다.
 

좋은 웹페이지 즐겨찾기