USBKEY 전체 해석 - 인증서 가 져 오기 (java)
16585 단어 CA 총동원
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 에 따라 인증 서 를 가 져 올 수 있 습 니 다.