package com.yussion.sign3;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.Security;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaCertStore;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.CMSProcessable;
import org.bouncycastle.cms.CMSProcessableByteArray;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.CMSSignedDataGenerator;
import org.bouncycastle.cms.CMSTypedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.operator.ContentSigner;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.encoders.Base64;
/**
* JCE: JCE(Java Cryptography Extension)是一组包,它们提供用于加密、密钥生成和协商以及 Message Authentication Code(MAC)算法的框架和实现。
* @author Administrator
*
*/
public class Test {
private static final String PRIVATE_KEY_PATH = "D:/cert/server.crt";
private static final String PRIVATE_KEY_PASSWORD="123456";
public static final String PUBLIC_KEY_PATH="D:/cert/client.crt";
public static void main(String[] args) throws Exception {
Security.addProvider(new BouncyCastleProvider());
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
KeyPair keyPair = kpg.generateKeyPair();
//String publicKey = Base64.toBase64String(keyPair.getPublic().getEncoded());
//MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAJoDxcklnoMi80m9K7LW2wFPPwY6W1srhZNuUoO54KS7g/f0ReLDtrfWOb7wPpXYnevanim0Zd5u/ugxnXF2T83xZxTABtIxAAK/FIRaUJQ9uNX6E4ehp4Vfr6dmYB/0cHj8Gt2VErW2Km5gqhHHSvJue8JnH/FsFQANoAf+lAkJAgMBAAECgYA8c9aiiX2ag5FzFCme3O7BqNVYIHfTZVXc9KS2x7MBdgjqvprf02pY5mFsLOij8I6sEPeb7w89K9wqT6845fOUiSfKt2n4t7G4hoNIdyMeqndHnCi0nsdKyTeEVBJU1FJXdjTYLZDqFcKYPQlvQrZWWmMDi3JBPxBzP3dSdwZnwQJBAONo1gukP+tj0FgZ37RWy47QpJxuzwm6s49ywTl8MvelPIf0WAlchZ7MX4BpDCRhGsLXGdXiuysirLjiDIUG1Z0CQQCtYLqsDvmYQ/EyHfZZMRkT9UTMGvDObAccNPZNJcICVdjPlaO8Q/wJY2mFRyY8rDXY2b31iQmoEfL/m9ktbntdAkEAprhiTHCjiABKa3y0m/MSE2b1d9ZpJTnikKVR8cITX6mdghLqRBq3v58X2P2qsDUcuIGYaE1saQhn1req9A/5pQJAe3/qmMM2AcNr3PJA17nEjlXowqbyH2gODIahZ8TclMNH5F5IOsQGlT1uHdTXpOJanPRFftA1w7W9bVw7cERBtQJAVrY47szawYwGrDhKlkiQw58l1s6lQtIcDlsKwXL6G0FnFsaddqSEbowx7iZUB52+Ux+0fDd+Z079m1FJDfKVGg==
String privateKey = Base64.toBase64String(keyPair.getPrivate().getEncoded());
byte[] keyBytes = Base64.decode(privateKey);
KeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey priKey = keyFactory.generatePrivate(keySpec);
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(priKey);
//CertificateFactory certificatefactory = CertificateFactory.getInstance("X.509", "BC");
//InputStream bais = new ByteArrayInputStream(privateKey.getBytes());
//X509Certificate cerx509 = (X509Certificate) certificatefactory.generateCertificate(bais);
X509Certificate cerx509 = getX509Certificate(PRIVATE_KEY_PATH); //new JcaX509CertificateConverter().getCertificate(new X509CertificateHolder());
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, cerx509));
List<Certificate> certList = new ArrayList<Certificate>();
certList.add(cerx509);
Store certs = new JcaCertStore(certList);
gen.addCertificates(certs);
byte[] signedBytes = sign(gen); //sign
unsign(signedBytes); //unsign
}
private static byte[] sign(CMSSignedDataGenerator gen) throws CMSException, IOException {
String content = "xxxxxx";
CMSTypedData cmsData = new CMSProcessableByteArray(content.getBytes());
CMSSignedData signedData = gen.generate(cmsData, true);
byte[] signedBytes = signedData.getEncoded();
return signedBytes;
}
private static void unsign(byte[] signedBytes)
throws CMSException, CertificateException, OperatorCreationException {
String signedStr = new String(Base64.encode(signedBytes));
CMSSignedData signedData = new CMSSignedData(Base64.decode(signedStr.getBytes()));
Store store = signedData.getCertificates();
SignerInformationStore signers = signedData.getSignerInfos();
Collection<SignerInformation> coll = signers.getSigners();
Iterator<SignerInformation> it = coll.iterator();
while(it.hasNext()) {
SignerInformation signer = it.next();
Collection certs = store.getMatches(signer.getSID());
Iterator certIt = certs.iterator();
X509CertificateHolder holder = (X509CertificateHolder)certIt.next();
X509Certificate cert = new JcaX509CertificateConverter().setProvider("BC").getCertificate(holder);
boolean result = signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert));
if(result) {
System.out.println("ok");
CMSProcessable sc = signedData.getSignedContent();
byte[] data = (byte[])sc.getContent();
System.out.println("oragin content: "+new String(data));
}
}
}
/**
* 获取公钥
*/
public static X509Certificate getX509Certificate(String crtFileName) {
try {
// 使用公钥对对称密钥进行加密 //若此处不加参数 "BC" 会报异常:CertificateException -
CertificateFactory certificatefactory = CertificateFactory.getInstance("X.509", "BC");
InputStream bais = new FileInputStream(crtFileName);
X509Certificate cert = (X509Certificate) certificatefactory.generateCertificate(bais);
return cert;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}