加解密核心工具(tool.encryptionAndDecryption.core)
*version 0.1.x
- 简介
- 安装
- ProviderMode描述类
- 配置类Base
- 配置根证书
- RSA\GM密钥对生成工具类(KeyPairTool)
- 密钥对工具类(KeyStoreTool)
- 公钥(PublicKey)公钥证书(X509Certificate)工具类(PublicKeyTool)
- 私钥(privateKey)工具类(privateKeyTool)
- 签名\验签、加密\解密(AsymmetricTool)
- RSA证书发证、使用
- GM双证发证流程
- 常见问题
简介
本工具类是基于bouncycastle的在封装,主要实现了如下功能
- 支持国密、RSA证书本地 生成、签发、签名\验签、加密\解密
- 支持国密单\双证 CA签发模式
- 支持RSA CA签发模式
- 支持MD5\SHA\SM3等摘要算法
- 支持AES\DES\SM4等对称加密算法
git: https://github.com/819548945/tool.encryptionAndDecryption.core
文档: http://doc.lich.me/0.1.x/encryptionAndDecryption.core.html
bug、意见反馈: liuchao_@outlook.com
安装
maven
<dependency>
<groupId>com.github.819548945</groupId>
<artifactId>tool.encryptionAndDecryption.core</artifactId>
<version>0.1.0</version>
</dependency>
ProviderMode描述类
类ProviderMode为算法叙述文件,可以方便的找到对应算法的参数,示例如下
ProviderMode.Asymmetric.GM.Cipher.SM2WITHSM3;//非对称加密.国密.加解密.加密散列hash算法为SM2WITHSM3
ProviderMode.Asymmetric.RSA.Signature.SHA1WithRSA;//非对称加密.RSA.签名.摘要算法为SHA1WithRSA
配置类Base
类Base为所有工具类的父类,主要用于基本功能的配置
配置SM1/SM4实现
在使用国密私钥证书时需要对加密结构体进行解密 SM4默认配置为ecb模式实现 SM1为非公开算法,需要自行实现 ,并通过接口配置
Base.setSm1ext(sm1ext);
Base.setSm4ext(sm4ext);
配置根证书
在使用本工具发证时,可以自定义根证书
Base.setGMroot(pk,cert);
Base.setRSAroot(pk,cert);
RSA\GM密钥对生成工具类(KeyPairTool)
KeyPair gmKeyPair=KeyPairTool.generateGMKeyPair();//国密密钥对生成
KeyPair rsaKeyPair=KeyPairTool.generateRSAKeyPair(1024);//RSA密钥对生成 参数为公钥长度
密钥对工具类(KeyStoreTool)
导出pfx(p12)
KeyStoreTool.toPKCS12(keyPair, pki, alias, pwd);
KeyStoreTool.toPKCS12(prk, certs, alias, pwd);
加载pfx(p12)
P12Data k=KeyStoreTool.loadPKCS12(p12, "123456");
k.getCert();//公钥证书
k.getPrivateKey();//私钥
k.getCertificateChain();//证书链jaca
生成PKCS10证书申请
KeyStoreTool.toPKCS10(k, "C=CN,O=lich", ProviderMode.Asymmetric.RSA.Signature.SHA1WithRSA);
KeyStoreTool.toPKCS10(prk,puk, "C=CN,O=lich", ProviderMode.Asymmetric.RSA.Signature.SHA1WithRSA);
公钥(PublicKey)公钥证书(X509Certificate)工具类(PublicKeyTool)
publicKey->x509Certificate
此过程生成的公钥证书为自签证书,不具备法律效应
PublicKeyTool.getX509Certificate(pki, pk);
x509Certificate->PublicKey
PublicKeyTool.x509CertificateToPublicKey(x509Certificate);
加载X509Certificate
PublicKeyTool.loadX509Certificate(x509Certificate);
生成X509Certificate
PublicKeyTool.getX509Certificate(publicKeyInfo,publicKey);
p7b、p7c相关
X509Certificate[] x509Certificates= PublicKeyTool.loadP7bToChain(p7bBytes,true);
X509Certificate x509Certificate= PublicKeyTool.loadP7bToX509Certificate(p7bBytes,true);
X509Certificate chain []= {PublicKeyTool.getRootGMX509Certificate(),x509Certificate};
byte[] p7b=PublicKeyTool.certificateChainToP7b(chain, true)
byte [][] chain1= {PublicKeyTool.getRootGMX509Certificate().getEncoded(),x509Certificate.getEncoded()};
byte[] p7b=PublicKeyTool.certificateChainToP7b(chain1, true)
注:该接口为0.1.6新增
加载 PublicKey
PublicKeyTool.toGMPublicKey(P);
PublicKeyTool.toRSAPublicKey(N);
PublicKeyTool.toRSAPublicKey(N,E);
获取公钥值
GM返回格式为 04|x|y RSA返回modulus
PublicKeyTool.getPublicKeyByte(publicKey);
私钥(privateKey)工具类(privateKeyTool)
加载私钥(GM)
PrivateKeyTool.toGMPrivateKey(d,P);
PrivateKeyTool.toGMPrivateKeyByEnvelopedKeyBlob(doubleprvkey);
PrivateKeyTool.toGMPrivateKeyByEnvelopedKeyBlob(doubleprvkey,privateKey);
PrivateKeyTool.toGMPrivateKeyBySignedAndEnvelopedData(doubleprvkey,puk);
PrivateKeyTool.toGMPrivateKeyBySignedAndEnvelopedData(doubleprvkey,privateKey,puk);
导出私钥加密保护结构(GM)
PrivateKeyTool.toEnvelopedKeyBlobByGMPrivateKey(privateKey);
PrivateKeyTool.toEnvelopedKeyBlobByGMPrivateKey(privateKey,encGmPublicKey);
加载私钥(RSA)
PrivateKeyTool.toRSAPrivateKey(pk);
签名\验签、加密\解密(AsymmetricTool)
签名
AsymmetricTool.sign(ori, privateKey, ProviderMode.Asymmetric.RSA.Signature.SHA256WithRSA);
AsymmetricTool.sign(ori, privateKey, cert);
验签
AsymmetricTool.verify(sign, ori, cert);
AsymmetricTool.verify(sign, ori, publicKey,ProviderMode.Asymmetric.RSA.Signature.SHA256WithRSA);
加密
AsymmetricTool.encrypt(ori, publicKey, ProviderMode.Asymmetric.RSA.Cipher.RSA);
解密
AsymmetricTool.decrypt(enc, privateKey, ProviderMode.Asymmetric.RSA.Cipher.RSA);
示例
RSA证书发证、使用
```java /**密钥生成*/ KeyPair kp=KeyPairTool.generateRSAKeyPair(2048); Date notBefore=new Date(); Calendar calendar = Calendar.getInstance(); calendar.add(Calendar.YEAR, 1); Date notAfter = calendar.getTime(); String subject="C=CN , CN=lich"; BigInteger serial=BigInteger.valueOf(System.currentTimeMillis()); PublicKeyInfo pki=new PublicKeyInfo(serial,notBefore, notAfter, subject); Certificate cert=PublicKeyTool.getX509Certificate(pki, kp.getPublic()); byte [] p12= KeyStoreTool.toPKCS12(kp.getPrivate(), new Certificate[] {cert}, "测试证书", "123456"); System.out.println("cer:"+Base64.encodeBase64String(cert.getEncoded())); System.out.println("pfx:"+Base64.encodeBase64String(p12)); /**密钥加载*/ P12Data k=KeyStoreTool.loadPKCS12(p12, "123456"); cert=k.getCert(); PrivateKey prk= k.getPrivateKey(); /**签名验签*/ byte[] ori="测试原文".getBytes("utf-8"); byte[] sign= AsymmetricTool.sign(ori, privateKey, (X509Certificate)cert); System.out.println("sign:"+Base64.encodeBase64String(sign)); System.out.println("verify:"+AsymmetricTool.verify(sign, ori, (X509Certificate)cert)); /**加解密*/ ori="加密原文".getBytes("utf-8"); byte [] enc=AsymmetricTool.encrypt(ori, publicKey, Provider.RSA.Cipher.RSA); System.out.println("enc:"+Base64.encodeBase64String(enc)); System.out.println("dec:"+new String(AsymmetricTool.decrypt(enc, privateKey, Provider.RSA.Cipher.RSA),"utf-8"));
### GM双证发证流程
```java
/**************发送CA数据***************/
String signKey= Base64.encodeBase64String(PublicKeyTool.getPublicKeyByte(Base.getRootGMX509Certificate().getPublicKey()));
/**************CA返回数据***************/
String signKeyCert="MIIDvTCCA2GgAwIBAgIIaeMAmgAlWT0wDAYIKoEcz1UBg3UFADB2MQswCQYDVQQGEwJDTjEOMAwGA1UECAwFQW5IdWkxDjAMBgNVBAcMBUhlRmVpMSYwJAYDVQQKDB1Bbkh1aSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTENMAsGA1UECwwEQUhDQTEQMA4GA1UEAwwHQUhDQVNNMjAeFw0yMTAxMDQwODA3NDJaFw0yMzAxMDQwODA3NDJaMCsxCzAJBgNVBAYTAkNOMQ0wCwYDVQQKDAR0ZXN0MQ0wCwYDVQQDDAR0ZXN0MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEHskcZtdrXttC6SkRTpUojOXQ63A7X23E3gjXrc3h9+1QE2Lv1jN1quL57299kQjC6rqxnwmMeGqlly9dVZ/3RqOCAiAwggIcMAwGA1UdEwQFMAMBAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMAsGA1UdDwQEAwIAwDAfBgNVHSMEGDAWgBRGmbxhYuK6U6kMiNLNXZbAyDC6zzCBygYDVR0fBIHCMIG/MIG8oIG5oIG2hoGObGRhcDovL2xkYXAuYWhlY2EuY246Mzg5L0NOPUFIQ0FTTTIsQ049QUhDQVNNMiwgT1U9Q1JMRGlzdHJpYnV0ZVBvaW50cywgbz1haGNhP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RjbGFzcz1jUkxEaXN0cmlidXRpb25Qb2ludIYjaHR0cDovL3d3dy5haGVjYS5jbi9jcmwvQUhDQVNNMi5jcmwwgdIGCCsGAQUFBwEBBIHFMIHCMIGLBggrBgEFBQcwAoZ/bGRhcDovL2xkYXAuYWhlY2EuY246Mzg5L0NOPUFIQ0FTTTIsQ049QUhDQVNNMiwgT1U9Y0FDZXJ0aWZpY2F0ZXMsIG89YWhjYT9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0Q2xhc3M9Y2VydGlmaWNhdGlvbkF1dGhvcml0eTAyBggrBgEFBQcwAoYmaHR0cDovL3d3dy5haGVjYS5jbi9jYWNlcnQvQUhDQVNNMi5jZXIwHQYDVR0OBBYEFFUmX9QRaIYPflfrIEwmc6+T8rSsMAwGCCqBHM9VAYN1BQADSAAwRQIhAMYenjVG/2YUhD1shHBhiBDrHG1q4sTSEiZ1zZ1GFOZRAiAwwhRCpoHtfdnQbdEVZubbK/Oz8+YoQnWFG2DGjLFSEA==";
String encKeyCert="MIIDszCCA1egAwIBAgIIaeMAfgAlWTwwDAYIKoEcz1UBg3UFADB2MQswCQYDVQQGEwJDTjEOMAwGA1UECAwFQW5IdWkxDjAMBgNVBAcMBUhlRmVpMSYwJAYDVQQKDB1Bbkh1aSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTENMAsGA1UECwwEQUhDQTEQMA4GA1UEAwwHQUhDQVNNMjAeFw0yMTAxMDQwODA3NDJaFw0yMzAxMDQwODA3NDJaMCsxCzAJBgNVBAYTAkNOMQ0wCwYDVQQKDAR0ZXN0MQ0wCwYDVQQDDAR0ZXN0MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEBKuHb+za3UnC989VEWZ7vPv9yZeZj0L4x0pVJtUyKfLC7TBCsGxviADKvpyrCUPHKpkr2feL5/tjLfEPBTZeoaOCAhYwggISMAwGA1UdEwQFMAMBAQAwEwYDVR0lBAwwCgYIKwYBBQUHAwQwCwYDVR0PBAQDAgAwMB8GA1UdIwQYMBaAFEaZvGFi4rpTqQyI0s1dlsDIMLrPMIHKBgNVHR8EgcIwgb8wgbyggbmggbaGgY5sZGFwOi8vbGRhcC5haGVjYS5jbjozODkvQ049QUhDQVNNMixDTj1BSENBU00yLCBPVT1DUkxEaXN0cmlidXRlUG9pbnRzLCBvPWFoY2E/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdD9iYXNlP29iamVjdGNsYXNzPWNSTERpc3RyaWJ1dGlvblBvaW50hiNodHRwOi8vd3d3LmFoZWNhLmNuL2NybC9BSENBU00yLmNybDCB0gYIKwYBBQUHAQEEgcUwgcIwgYsGCCsGAQUFBzAChn9sZGFwOi8vbGRhcC5haGVjYS5jbjozODkvQ049QUhDQVNNMixDTj1BSENBU00yLCBPVT1jQUNlcnRpZmljYXRlcywgbz1haGNhP2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0aG9yaXR5MDIGCCsGAQUFBzAChiZodHRwOi8vd3d3LmFoZWNhLmNuL2NhY2VydC9BSENBU00yLmNlcjAdBgNVHQ4EFgQUoYGcKEuC2bCcA1fA4yNOMDgxyF4wDAYIKoEcz1UBg3UFAANIADBFAiEA1ft9BCho5QC3iJgu25eyV9I6VVe1zMaH0Grbbfz7cV4CIC+Xo7Tf7gakzDHqKeRaFxJfRXG+YwVF7+O8IIv4RysY";
String encKeyProtection="AQAAAAEEAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADpP5zcN19xOUNSQQJ+UwfUUJYxw2PfPxMN9JgsUm0qCQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASrh2/s2t1JwvfPVRFme7z7/cmXmY9C+MdKVSbVMinyAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADC7TBCsGxviADKvpyrCUPHKpkr2feL5/tjLfEPBTZeoQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAocuNU15U9QhNzasMrllYeTC5+ocIXanU4/2BK0XeYwkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAawWjtJAUzoOLgsgcyaWZdikDxakN1qKyx3kkEdBOH+wi2yU1jjbGO2Fq8rZtY0ILinbzovrZAhLLDh5UYaMzQQAAAAxr22PeNfWLd0J8A8BdNRew==";
String decKeyProtection=Base64.encodeBase64String(PrivateKeyTool.toEnvelopedKeyBlobByGMPrivateKey(Base.getRootGMPrivateKey()));
PrivateKey prkSign=PrivateKeyTool.toGMPrivateKeyByEnvelopedKeyBlob(Base64.decodeBase64(decKeyProtection));
PrivateKey prkEnc=PrivateKeyTool.toGMPrivateKeyByEnvelopedKeyBlob(Base64.decodeBase64(encKeyProtection));
Certificate certificateSignKey=PublicKeyTool.loadX509Certificate(Base64.decodeBase64(signKeyCert));
Certificate certificateEncKey=PublicKeyTool.loadX509Certificate(Base64.decodeBase64(encKeyCert));
byte[] ori="测试原文".getBytes("utf-8");
System.out.println("-----------签名证书测试-----------");
byte[] sign= AsymmetricTool.sign(ori, prkSign, (X509Certificate)certificateSignKey);
System.out.println("sign:"+Base64.encodeBase64String(sign));
System.out.println("verify:"+AsymmetricTool.verify(sign, ori, (X509Certificate)certificateSignKey));
ori="加密原文".getBytes("utf-8");
byte [] enc=AsymmetricTool.encrypt(ori, certificateSignKey.getPublicKey(), ProviderMode.Asymmetric.GM.Cipher.SM2);
System.out.println("enc:"+Base64.encodeBase64String(enc));
System.out.println("ori:"+new String(AsymmetricTool.decrypt(enc, prkSign, ProviderMode.Asymmetric.GM.Cipher.SM2),"utf-8"));
System.out.println("-----------加密签名证书测试-----------");
sign= AsymmetricTool.sign(ori, prkEnc, (X509Certificate)certificateEncKey);
System.out.println("sign:"+Base64.encodeBase64String(sign));
System.out.println("verify:"+AsymmetricTool.verify(sign, ori, (X509Certificate)certificateEncKey));
ori="加密原文".getBytes("utf-8");
enc=AsymmetricTool.encrypt(ori, certificateEncKey.getPublicKey(),ProviderMode.Asymmetric.GM.Cipher.SM2);
System.out.println("enc:"+Base64.encodeBase64String(enc));
System.out.println("ori:"+new String(AsymmetricTool.decrypt(enc, prkEnc, ProviderMode.Asymmetric.GM.Cipher.SM2),"utf-8"));
}
常见问题
Illegal key size or default parameters
该问题是由于低版本jdk对秘钥进行了限制,可通过替换策略文件进行替换
JDK8: 其对应的JCE下载地址为:http://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html
下载完后,解压,将其中的“local_policy.jar ”和“US_export_policy.jar”两个文件替换掉自己%JAVE_HOME%\jre\lib\security文件夹下对应的原文件(%JAVE_HOME%是自己电脑的Java路径)。
JDK7: 其对应的JCE下载地址为:http://www.oracle.com/technetwork/java/javase/downloads/jce-7-download-432124.html
下载完后,解压,将其中的“local_policy.jar ”和“US_export_policy.jar”两个文件替换掉自己%JAVE_HOME%\jre\lib\security文件夹下对应的原文件(%JAVE_HOME%是自己电脑的Java路径)。