同步代码
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
package com.chakracoin.shsm.cert;
|
||||
|
||||
|
||||
import com.sunyard.ssp.BytesUtil;
|
||||
import org.bouncycastle.asn1.ASN1OctetString;
|
||||
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
|
||||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
|
||||
import org.bouncycastle.asn1.x9.X9ECPoint;
|
||||
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
|
||||
import org.bouncycastle.crypto.params.ECDomainParameters;
|
||||
import org.bouncycastle.jcajce.provider.asymmetric.util.KeyUtil;
|
||||
import org.bouncycastle.jce.ECNamedCurveTable;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.jce.spec.ECNamedCurveParameterSpec;
|
||||
import org.bouncycastle.math.ec.ECCurve;
|
||||
import org.bouncycastle.math.ec.ECPoint;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
|
||||
import static com.chakracoin.shsm.logiclayer.cert.SM2PublicKey.ID_SM2_PUBKEY_PARAM;
|
||||
|
||||
public class QPublicKey implements PublicKey {
|
||||
|
||||
private ECPoint q;
|
||||
|
||||
public QPublicKey(ECPoint q) {
|
||||
this.q = q;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return "EC";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return "PKCS#8";
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
ASN1OctetString p = ASN1OctetString.getInstance(
|
||||
new X9ECPoint(q, false).toASN1Primitive());
|
||||
|
||||
// stored curve is null if ImplicitlyCa
|
||||
SubjectPublicKeyInfo info = new SubjectPublicKeyInfo(
|
||||
new AlgorithmIdentifier(X9ObjectIdentifiers.id_ecPublicKey, ID_SM2_PUBKEY_PARAM),
|
||||
p.getOctets());
|
||||
|
||||
byte[]s= KeyUtil.getEncodedSubjectPublicKeyInfo(info);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
public static QPublicKey getQPublicKey(String der) throws NoSuchAlgorithmException, NoSuchProviderException {
|
||||
|
||||
if (null == der || !der.startsWith("03420004") ) {
|
||||
throw new IllegalArgumentException("公钥格式错误");
|
||||
}
|
||||
|
||||
int headLen = 8;
|
||||
int len = ( der.length() - 8 ) / 2;
|
||||
|
||||
String strcertPKX = der.substring(headLen, headLen + 64);
|
||||
String strcertPKY = der.substring(headLen + len, headLen + len + 64);
|
||||
|
||||
BigInteger biX = new BigInteger(strcertPKX, 16);
|
||||
BigInteger biY = new BigInteger(strcertPKY, 16);
|
||||
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); //载入bc库的支持
|
||||
|
||||
ECNamedCurveParameterSpec spec = ECNamedCurveTable.getParameterSpec("sm2p256v1"); //获取bc库内置曲线参数,曲线名称sm2p256v1
|
||||
|
||||
ECDomainParameters ecDomainParameters = new ECDomainParameters(spec.getCurve(), spec.getG(), spec.getN());
|
||||
|
||||
|
||||
ECCurve ecurve = ecDomainParameters.getCurve(); //获取曲线对象
|
||||
|
||||
ECPoint q = ecurve.createPoint(biX, biY); //创建公钥点
|
||||
|
||||
return new QPublicKey( q );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.chakracoin.shsm.cert;
|
||||
|
||||
|
||||
import com.sunyard.ssp.BytesUtil;
|
||||
|
||||
import java.security.PublicKey;
|
||||
|
||||
public class SimplePublicKey implements PublicKey {
|
||||
|
||||
private byte[] encoded;
|
||||
|
||||
public SimplePublicKey(String str) {
|
||||
this.encoded = BytesUtil.hexString2Bytes( str );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAlgorithm() {
|
||||
return "EC";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFormat() {
|
||||
return "PKCS#8";
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] getEncoded() {
|
||||
return this.encoded;
|
||||
}
|
||||
|
||||
|
||||
public static SimplePublicKey getSimplePublickKey(String der) {
|
||||
|
||||
if (null == der || !der.startsWith("03420004") ) {
|
||||
throw new IllegalArgumentException("公钥格式错误");
|
||||
}
|
||||
|
||||
int headLen = 8;
|
||||
int len = ( der.length() - 8 ) / 2;
|
||||
|
||||
String strcertPKX = der.substring(headLen, headLen + 64);
|
||||
String strcertPKY = der.substring(headLen + len, headLen + len + 64);
|
||||
der = "03420004" + strcertPKX + strcertPKY;
|
||||
|
||||
return new SimplePublicKey("3059301306072A8648CE3D020106082A811CCF5501822D" + der );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$" isTestSource="false" packagePrefix="com.chakracoin.shsm" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,197 @@
|
||||
//package mx.com.mostrotuille.example.cms;
|
||||
//
|
||||
//import java.io.ByteArrayInputStream;
|
||||
//import java.io.ByteArrayOutputStream;
|
||||
//import java.io.InputStream;
|
||||
//import java.security.KeyFactory;
|
||||
//import java.security.KeyStore;
|
||||
//import java.security.PrivateKey;
|
||||
//import java.security.Security;
|
||||
//import java.security.cert.CertificateFactory;
|
||||
//import java.security.cert.X509Certificate;
|
||||
//import java.security.spec.PKCS8EncodedKeySpec;
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.Base64;
|
||||
//import java.util.Collection;
|
||||
//import java.util.List;
|
||||
//
|
||||
//import org.bouncycastle.asn1.ASN1InputStream;
|
||||
//import org.bouncycastle.asn1.cms.ContentInfo;
|
||||
//import org.bouncycastle.cert.X509CertificateHolder;
|
||||
//import org.bouncycastle.cert.jcajce.JcaCertStore;
|
||||
//import org.bouncycastle.cms.CMSAlgorithm;
|
||||
//import org.bouncycastle.cms.CMSEnvelopedData;
|
||||
//import org.bouncycastle.cms.CMSEnvelopedDataGenerator;
|
||||
//import org.bouncycastle.cms.CMSProcessableByteArray;
|
||||
//import org.bouncycastle.cms.CMSSignedData;
|
||||
//import org.bouncycastle.cms.CMSSignedDataGenerator;
|
||||
//import org.bouncycastle.cms.KeyTransRecipientInformation;
|
||||
//import org.bouncycastle.cms.RecipientInformation;
|
||||
//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.cms.jcajce.JceCMSContentEncryptorBuilder;
|
||||
//import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
|
||||
//import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
|
||||
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
//import org.bouncycastle.operator.OutputEncryptor;
|
||||
//import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
//import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
|
||||
//import org.bouncycastle.util.Store;
|
||||
//
|
||||
//public class CmsApplication {
|
||||
// public static byte[] decrypt(byte[] encryptedData, PrivateKey privateKey) throws Exception {
|
||||
// final CMSEnvelopedData envelopedData = new CMSEnvelopedData(encryptedData);
|
||||
//
|
||||
// final Collection<RecipientInformation> recipients = envelopedData.getRecipientInfos().getRecipients();
|
||||
//
|
||||
// final KeyTransRecipientInformation recipientInformation = (KeyTransRecipientInformation) recipients.iterator()
|
||||
// .next();
|
||||
//
|
||||
// return recipientInformation.getContent(new JceKeyTransEnvelopedRecipient(privateKey));
|
||||
// }
|
||||
//
|
||||
// public static byte[] encrypt(byte[] data, X509Certificate x509Certificate) throws Exception {
|
||||
// final CMSEnvelopedDataGenerator cmsEnvelopedDataGenerator = new CMSEnvelopedDataGenerator();
|
||||
// cmsEnvelopedDataGenerator.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(x509Certificate));
|
||||
//
|
||||
// final OutputEncryptor outputEncryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC)
|
||||
// .setProvider(BouncyCastleProvider.PROVIDER_NAME).build();
|
||||
//
|
||||
// final CMSEnvelopedData cmsEnvelopedData = cmsEnvelopedDataGenerator.generate(new CMSProcessableByteArray(data),
|
||||
// outputEncryptor);
|
||||
//
|
||||
// return cmsEnvelopedData.getEncoded();
|
||||
// }
|
||||
//
|
||||
// public static KeyStore getKeystore(InputStream keyStoreInputStream, String keyStorePassword) throws Exception {
|
||||
// final KeyStore result = KeyStore.getInstance("jks");
|
||||
// result.load(keyStoreInputStream, keyStorePassword.toCharArray());
|
||||
//
|
||||
// return result;
|
||||
// }
|
||||
//
|
||||
// public static PrivateKey getPrivateKey(InputStream privateKeyInputStream, String password) throws Exception {
|
||||
// final PKCS8Key pkcs8Key = new PKCS8Key(privateKeyInputStream, password.toCharArray());
|
||||
//
|
||||
// final KeyFactory keyFactory = KeyFactory.getInstance("RSA");
|
||||
//
|
||||
// final PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(pkcs8Key.getDecryptedBytes());
|
||||
//
|
||||
// return keyFactory.generatePrivate(pkcs8EncodedKeySpec);
|
||||
// }
|
||||
//
|
||||
// public static PrivateKey getPrivateKey(KeyStore keyStore, String alias, String password) throws Exception {
|
||||
// return (PrivateKey) keyStore.getKey(alias, password.toCharArray());
|
||||
// }
|
||||
//
|
||||
// public static X509Certificate getX509Certificate(InputStream certificateInputStream) throws Exception {
|
||||
// return (X509Certificate) CertificateFactory.getInstance("X.509").generateCertificate(certificateInputStream);
|
||||
// }
|
||||
//
|
||||
// public static void main(final String[] ar) {
|
||||
// try {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
//
|
||||
// final ClassLoader classLoader = CmsApplication.class.getClassLoader();
|
||||
//
|
||||
// final KeyStore keyStore = getKeystore(classLoader.getResourceAsStream("keystore.jks"), "mystorepassword");
|
||||
//
|
||||
// final String message = "Hello, world!";
|
||||
//
|
||||
// System.out.println("Data:\n" + message);
|
||||
//
|
||||
// byte[] signedData = sign(message.getBytes(),
|
||||
// getX509Certificate(classLoader.getResourceAsStream("remitent.cer")),
|
||||
// getPrivateKey(keyStore, "remitent_key", "remitentpassword"));
|
||||
//
|
||||
// byte[] encryptedData = encrypt(signedData,
|
||||
// getX509Certificate(classLoader.getResourceAsStream("destinatary.cer")));
|
||||
//
|
||||
// final String encryptedDataBase64 = Base64.getEncoder().encodeToString(encryptedData);
|
||||
//
|
||||
// System.out.println("\nEncrypted data (base 64):\n" + encryptedDataBase64);
|
||||
//
|
||||
// byte[] decryptedData = decrypt(Base64.getDecoder().decode(encryptedDataBase64),
|
||||
// getPrivateKey(keyStore, "destinatary_key", "destinatarypassword"));
|
||||
//
|
||||
// if (verifySign(decryptedData)) {
|
||||
// byte[] data = unsign(decryptedData);
|
||||
//
|
||||
// System.out.println("\nDecrypted data:\n" + new String(data));
|
||||
// }
|
||||
// } catch (Exception ex) {
|
||||
// ex.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static byte[] sign(byte[] data, X509Certificate x509Certificate, PrivateKey privateKey) throws Exception {
|
||||
// final List<X509Certificate> x509CertificateList = new ArrayList<X509Certificate>();
|
||||
// x509CertificateList.add(x509Certificate);
|
||||
//
|
||||
// final CMSSignedDataGenerator cmsGenerator = new CMSSignedDataGenerator();
|
||||
// cmsGenerator.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
|
||||
// new JcaDigestCalculatorProviderBuilder().setProvider(BouncyCastleProvider.PROVIDER_NAME).build())
|
||||
// .build(new JcaContentSignerBuilder("SHA256withRSA").build(privateKey), x509Certificate));
|
||||
// cmsGenerator.addCertificates(new JcaCertStore(x509CertificateList));
|
||||
//
|
||||
// final CMSSignedData cmsSignedData = cmsGenerator.generate(new CMSProcessableByteArray(data), true);
|
||||
//
|
||||
// return cmsSignedData.getEncoded();
|
||||
// }
|
||||
//
|
||||
// public static byte[] unsign(byte[] decryptedData) throws Exception {
|
||||
// final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
//
|
||||
// final CMSSignedData cmsSignedData = new CMSSignedData(decryptedData);
|
||||
// cmsSignedData.getSignedContent().write(outputStream);
|
||||
//
|
||||
// return outputStream.toByteArray();
|
||||
// }
|
||||
//
|
||||
// @SuppressWarnings("unchecked")
|
||||
// public static boolean verifySign(byte[] signedData) throws Exception {
|
||||
// ByteArrayInputStream inputStream = null;
|
||||
// ASN1InputStream asn1InputStream = null;
|
||||
//
|
||||
// try {
|
||||
// inputStream = new ByteArrayInputStream(signedData);
|
||||
// asn1InputStream = new ASN1InputStream(inputStream);
|
||||
//
|
||||
// final CMSSignedData cmsSignedData = new CMSSignedData(
|
||||
// ContentInfo.getInstance(asn1InputStream.readObject()));
|
||||
//
|
||||
// final Store<X509CertificateHolder> certificates = cmsSignedData.getCertificates();
|
||||
//
|
||||
// final SignerInformationStore signerInformationStore = cmsSignedData.getSignerInfos();
|
||||
//
|
||||
// final Collection<SignerInformation> signers = signerInformationStore.getSigners();
|
||||
//
|
||||
// final SignerInformation signer = signers.iterator().next();
|
||||
//
|
||||
// final X509CertificateHolder x509CertificateHolder = ((Collection<X509CertificateHolder>) certificates
|
||||
// .getMatches(signer.getSID())).iterator().next();
|
||||
//
|
||||
// return signer.verify(new JcaSimpleSignerInfoVerifierBuilder().build(x509CertificateHolder));
|
||||
// } catch (Exception ex) {
|
||||
// throw ex;
|
||||
// } finally {
|
||||
// if (asn1InputStream != null) {
|
||||
// try {
|
||||
// asn1InputStream.close();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (inputStream != null) {
|
||||
// try {
|
||||
// inputStream.close();
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.chakracoin.shsm.test;
|
||||
|
||||
import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.openssl.PEMParser;
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
||||
import org.bouncycastle.openssl.jcajce.JceOpenSSLPKCS8DecryptorProviderBuilder;
|
||||
import org.bouncycastle.operator.InputDecryptorProvider;
|
||||
import org.bouncycastle.operator.OperatorCreationException;
|
||||
import org.bouncycastle.pkcs.PKCS8EncryptedPrivateKeyInfo;
|
||||
import org.bouncycastle.pkcs.PKCSException;
|
||||
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Security;
|
||||
import java.security.cert.CertificateException;
|
||||
|
||||
public class Keytools {
|
||||
public static void main(String[] args) throws Exception {
|
||||
readPem("D:\\fullstack\\gateway\\nginx\\test\\certs\\signkey.pem", "123456");
|
||||
}
|
||||
|
||||
static PrivateKey readPem(String path, String password)
|
||||
throws IOException, CertificateException, OperatorCreationException, PKCSException {
|
||||
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
PEMParser pemParser = new PEMParser(new FileReader(new File(path)));
|
||||
PrivateKey privateKey = null;
|
||||
X509Certificate cert = null;
|
||||
Object object = pemParser.readObject();
|
||||
|
||||
while (object != null) {
|
||||
JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider("BC");
|
||||
if (object instanceof X509CertificateHolder) {
|
||||
cert = new JcaX509CertificateConverter().getCertificate((X509CertificateHolder) object);
|
||||
}
|
||||
if (object instanceof PKCS8EncryptedPrivateKeyInfo) {
|
||||
PKCS8EncryptedPrivateKeyInfo pinfo = (PKCS8EncryptedPrivateKeyInfo) object;
|
||||
InputDecryptorProvider provider = new JceOpenSSLPKCS8DecryptorProviderBuilder().build(password.toCharArray());
|
||||
PrivateKeyInfo info = pinfo.decryptPrivateKeyInfo(provider);
|
||||
privateKey = converter.getPrivateKey(info);
|
||||
}
|
||||
if (object instanceof PrivateKeyInfo) {
|
||||
privateKey = converter.getPrivateKey((PrivateKeyInfo) object);
|
||||
}
|
||||
object = pemParser.readObject();
|
||||
}
|
||||
|
||||
return privateKey;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
package com.chakracoin.shsm.test;
|
||||
|
||||
|
||||
import javax.crypto.SecretKeyFactory;
|
||||
import javax.crypto.spec.PBEKeySpec;
|
||||
import java.math.BigInteger;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.KeySpec;
|
||||
|
||||
/**
|
||||
* PBKDF2加密工具
|
||||
* @author TF
|
||||
*/
|
||||
|
||||
public class PBKDF2Tool{
|
||||
|
||||
/**
|
||||
* 算法
|
||||
*/
|
||||
public static final String PBKDF2_ALGORITHM = "PBKDF2WithHmacSHA1";
|
||||
/**
|
||||
* 盐的长度
|
||||
*/
|
||||
public static final int SALT_BYTE_SIZE = 32 / 2;
|
||||
/**
|
||||
* 生成密文的长度
|
||||
*/
|
||||
public static final int HASH_BIT_SIZE = 128 * 4;
|
||||
/**
|
||||
* 迭代次数
|
||||
*/
|
||||
public static final int PBKDF2_ITERATIONS = 1000;
|
||||
|
||||
/**
|
||||
* @describe: 对输入的密码进行验证
|
||||
* @param: [attemptedPassword(待验证密码), encryptedPassword(密文), salt(盐值)]
|
||||
* @return: boolean
|
||||
*/
|
||||
private static boolean authenticate(String attemptedPassword, String encryptedPassword, String salt)
|
||||
throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
// 用相同的盐值对用户输入的密码进行加密
|
||||
String encryptedAttemptedPassword = getEncryptedPassword(attemptedPassword, salt);
|
||||
// 把加密后的密文和原密文进行比较,相同则验证成功,否则失败
|
||||
return encryptedAttemptedPassword.equals(encryptedPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* @describe: 生成密文
|
||||
* @param: [password(明文密码), salt(盐值)]
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
private static String getEncryptedPassword(String password, String salt) throws NoSuchAlgorithmException,
|
||||
InvalidKeySpecException {
|
||||
//参数 :明文密码 ,盐值,和迭代次数和长度生成密文
|
||||
KeySpec spec = new PBEKeySpec(password.toCharArray(), fromHex(salt), PBKDF2_ITERATIONS, HASH_BIT_SIZE);
|
||||
//返回转换指定算法的秘密密钥的 SecretKeyFactory 对象
|
||||
//此方法从首选 Provider 开始遍历已注册安全提供者列表。返回一个封装 SecretKeyFactorySpi 实现的新 SecretKeyFactory 对象,该实现取自支持指定算法的第一个 Provider。
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
|
||||
//根据提供的密钥规范(密钥材料)生成 SecretKey 对象。 然后以主要编码格式返回键,最后转换为16进制字符串
|
||||
return toHex(factory.generateSecret(spec).getEncoded());
|
||||
}
|
||||
|
||||
|
||||
public static String gen(String message, String salt, int c, int dkLen) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
//参数 :明文密码 ,盐值,和迭代次数和长度生成密文
|
||||
KeySpec spec = new PBEKeySpec(message.toCharArray(), fromHex(salt), c, dkLen * 8);
|
||||
//返回转换指定算法的秘密密钥的 SecretKeyFactory 对象
|
||||
//此方法从首选 Provider 开始遍历已注册安全提供者列表。返回一个封装 SecretKeyFactorySpi 实现的新 SecretKeyFactory 对象,该实现取自支持指定算法的第一个 Provider。
|
||||
SecretKeyFactory factory = SecretKeyFactory.getInstance(PBKDF2_ALGORITHM);
|
||||
//根据提供的密钥规范(密钥材料)生成 SecretKey 对象。 然后以主要编码格式返回键,最后转换为16进制字符串
|
||||
return toHex(factory.generateSecret(spec).getEncoded());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @describe: 通过加密的强随机数生成盐(最后转换为16进制)
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
private static String generateSalt() throws NoSuchAlgorithmException {
|
||||
//返回一个实现指定的 SecureRandom 对象
|
||||
//随机数生成器 (RNG) 算法。
|
||||
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
|
||||
//生成盐
|
||||
byte[] salt = new byte[SALT_BYTE_SIZE];
|
||||
random.nextBytes(salt);
|
||||
//返回16进制的字符串
|
||||
return toHex(salt);
|
||||
}
|
||||
|
||||
/**
|
||||
* @describe: 十六进制字符串转二进制字符串
|
||||
* @param: [hex]
|
||||
* @return: byte[]
|
||||
*/
|
||||
private static byte[] fromHex(String hex) {
|
||||
byte[] binary = new byte[hex.length() / 2];
|
||||
for (int i = 0; i < binary.length; i++) {
|
||||
binary[i] = (byte) Integer.parseInt(hex.substring(2 * i, 2 * i + 2), 16);
|
||||
}
|
||||
return binary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @describe: 二进制字符串转十六进制字符串
|
||||
* @param: [array]
|
||||
* @return: java.lang.String
|
||||
*/
|
||||
private static String toHex(byte[] array) {
|
||||
BigInteger bigInteger = new BigInteger(1, array);
|
||||
String hex = bigInteger.toString(16);
|
||||
int paddingLength = (array.length * 2) - hex.length();
|
||||
if (paddingLength > 0) {
|
||||
return String.format("%0" + paddingLength + "d", 0) + hex;
|
||||
} else {
|
||||
return hex;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成可以保存的数据
|
||||
* @param password 明文
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws InvalidKeySpecException
|
||||
*/
|
||||
public static String generateStorngPasswordHash(String password) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
//先获取盐值
|
||||
String salt = PBKDF2Tool.generateSalt();
|
||||
//生成密文
|
||||
String hash =PBKDF2Tool.getEncryptedPassword(password,salt);
|
||||
return salt + ":" + hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* 明文密码和数据库保存的值比较
|
||||
* @param originalPassword 明文密码
|
||||
* @param storedPassword 数据库保存的值
|
||||
* @throws NoSuchAlgorithmException
|
||||
* @throws InvalidKeySpecException
|
||||
*/
|
||||
public static boolean validatePassword(String originalPassword, String storedPassword) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
String[] parts = storedPassword.split(":");
|
||||
String salt = parts[0];
|
||||
String hash = parts[1];
|
||||
return PBKDF2Tool.authenticate(originalPassword,hash,salt);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package com.chakracoin.shsm.test;
|
||||
|
||||
import cn.hutool.core.bean.BeanUtil;
|
||||
import com.chakracoin.shsm.cert.TestX509;
|
||||
import com.chakracoin.shsm.util.Util;
|
||||
import com.sunyard.ssp.BytesUtil;
|
||||
import lombok.SneakyThrows;
|
||||
import org.bouncycastle.asn1.*;
|
||||
import org.bouncycastle.asn1.cms.ContentInfo;
|
||||
import org.bouncycastle.cms.CMSEnvelopedData;
|
||||
import org.bouncycastle.cms.SydCmsUtil;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
import javax.security.auth.x500.X500Principal;
|
||||
import java.io.*;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PKCS7Test {
|
||||
|
||||
public static void write(String path, byte[] data){
|
||||
try {
|
||||
File f = new File( path );
|
||||
if ( f.exists() ) {
|
||||
f.createNewFile();
|
||||
}
|
||||
FileOutputStream out = new FileOutputStream( f );
|
||||
try {
|
||||
out.write( data );
|
||||
out.flush();
|
||||
out.close();
|
||||
} finally {
|
||||
out.close();
|
||||
}
|
||||
}catch ( Exception e ){
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static String read(String path){
|
||||
InputStream is = PKCS7Test.class.getResourceAsStream( path );
|
||||
try {
|
||||
byte[] buff = new byte[ is.available() ];
|
||||
is.read( buff );
|
||||
return new String(buff);
|
||||
} catch ( Exception e ){
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
private static final String dn8010(){
|
||||
byte[] dn = "C=CN,O=CFCA OCA1,OU=YCCA,OU=Individual-2,CN=YCCA@黄金交易所@Zhuangj@1".getBytes("GBK");
|
||||
|
||||
byte[] data = new byte[256];
|
||||
Arrays.fill( data, (byte) 0 );
|
||||
System.arraycopy( dn, 0, data, 0, dn.length);
|
||||
|
||||
ByteBuffer bb = ByteBuffer.allocate( 2 + data.length );
|
||||
bb.put( (byte)0x80 );
|
||||
bb.put( (byte)0x10 );
|
||||
bb.put( data );
|
||||
|
||||
return Util.bytes2HexString( bb.array() );
|
||||
}
|
||||
|
||||
|
||||
private static void update(ContentInfo info, byte[] sessionKeyDer, byte[] enData , String sn, Map<String, String>issuer ) throws UnsupportedEncodingException {
|
||||
// 修改
|
||||
ASN1Sequence seq = (ASN1Sequence) info.getContent().toASN1Primitive();
|
||||
|
||||
ASN1Set set = ASN1Set.getInstance(seq.getObjectAt(1).toASN1Primitive());
|
||||
ASN1Sequence seq2 = (ASN1Sequence) set.getObjectAt( 0 ).toASN1Primitive();
|
||||
|
||||
// 会话密钥
|
||||
DEROctetString key = (DEROctetString) seq2.getObjectAt( 3 );
|
||||
BeanUtil.setFieldValue(key, "string", sessionKeyDer);
|
||||
|
||||
// 签发信息段
|
||||
ASN1Sequence seq3 = (ASN1Sequence) seq2.getObjectAt( 1 ).toASN1Primitive();
|
||||
ASN1Integer isn = (ASN1Integer) seq3.getObjectAt(1 ).toASN1Primitive();
|
||||
BeanUtil.setFieldValue( isn, "bytes", Util.hexString2Bytes( sn ) );
|
||||
|
||||
|
||||
ASN1Sequence seq4 = (ASN1Sequence) seq3.getObjectAt( 0 ).toASN1Primitive();
|
||||
ASN1Set setO = (ASN1Set) seq4.getObjectAt(1).toASN1Primitive();
|
||||
ASN1Sequence seqO = (ASN1Sequence) setO.getObjectAt(0).toASN1Primitive();
|
||||
DERUTF8String o = (DERUTF8String) seqO.getObjectAt(1).toASN1Primitive();
|
||||
BeanUtil.setFieldValue(o, "string", issuer.get("O").getBytes("UTF-8") );
|
||||
|
||||
ASN1Set setCN = (ASN1Set) seq4.getObjectAt(2).toASN1Primitive();
|
||||
ASN1Sequence seqCn = (ASN1Sequence) setCN.getObjectAt(0).toASN1Primitive();
|
||||
DERUTF8String Cn = (DERUTF8String) seqCn.getObjectAt(1).toASN1Primitive();
|
||||
BeanUtil.setFieldValue(Cn, "string", issuer.get("CN").getBytes("UTF-8") );
|
||||
|
||||
// 密文段
|
||||
ASN1Sequence seq5 = (ASN1Sequence) seq.getObjectAt( 2 ).toASN1Primitive();
|
||||
ASN1TaggedObject tag = (ASN1TaggedObject) seq5.getObjectAt(2).toASN1Primitive();
|
||||
DEROctetString data = (DEROctetString) tag.getObject();
|
||||
BeanUtil.setFieldValue(data, "string", enData);
|
||||
}
|
||||
|
||||
|
||||
@SneakyThrows
|
||||
public static void main(String[] args) {
|
||||
|
||||
|
||||
System.out.println( new String( Util.encodeBase64( Util.hexString2Bytes( "308206F3060A2A811CCF550601040203A08206E3308206DF0201003181F83081F50201003065305C310B300906035504061302434E3130302E060355040A0C274368696E612046696E616E6369616C2043657274696669636174696F6E20417574686F72697479311B301906035504030C1243464341205445535420534D32204F43413102051049831419300D06092A811CCF5501822D030500047A307802205116E5F25813AF0D2040644B957B7CAE9E68E9E87BB3AE5D3CB39E239CD0C36502202FD68A8502A2D7003F61BBA2E8D77961C2B2384073DA20BE29B93F6716D1ADDF042042710FF6D9B44877F36BF7964351364F38293D15DE071D02B58DED7E55064135041071F2751A6C5B5706001C7FDFEA619645308205DD060A2A811CCF550601040201301B06072A811CCF55016804103ABB33F57AA5E2D454367BE8B31DC7C7808205B0ADEC723D48E3E1D11E7DDC540742283C98A24A101E19C2CD7DAE99ED499D7C8BBEEB6E3BF28AD63E00E821393F5250BA1C875355AD91A6ADF8A8B899EEB2AEB719EDE451B6881550DB5B8032C97DA4C07F474998E8663447CAD702AEC10C01A3B11B5D23A9FB02307B4C9B232C5B23509E58E3D0AAD3C84E953C2707D46F7359DCC6222C69D0A2257D5254F1E5CD1D685A9F48C38BB92709AACC23F5ABDBC9BC1D720A578C145A52AFD760E9176F8731037BD0AF7D8DFE303283FE9F497EDFCA15AE57B1A739A903C644BA79C065705DA7EE04BF0AB4CAE6FEBC7747508A95D7C320EB092EA321F1E4DACCDB5F0FB13AF88E7E53E352E86284880027255C8DE166808B7BF86CCC453B7CE48BBBBC8F5CEF36F06C7BCB1517DD91FFAAC0DD1CF45DF12584323EEE78A3536B2C2F939B77859200E8E6C8F628D62C1FDA87632821047999756E6DF5D65C5A8D8A37FF8EAE891B9307F27F488B3B3F0604AB2455550D3A6EE9B288260FD2EE481B4553DB6211A22EA66ED34406F30788DCD6C917426E771A113D49154D891841F14424786E7AE00FE88B8D98D74DC284EB9A645D27F9C37E7DE12E4F3EFA0D2686F1E42AF26153F705FC80D5EB9FF3AA6BCA920C6A9E3D84485E1335CF4A261E052368A0BB9C64E50EEC8D24DF2BDE58AF43ED1C0C3BEA4B1DB32D0E5ECD1D2FFD641557B558E67871F27343217991B0CC4A5AC568A9FEE0500060B4BECD085DD54A2E87B2F5BB3C3132F725ACB72577BA3C920095431652D662889189E843A90857ACDBDBF2F1B638CCA59E65AD06A7CB1644F82E412E7CD9892F17E10E0888B255FD9905EB4F6FA1E4C6056910262F57CF41839CB5F27099080AB7A514499D7A141C1B1E816EA40AD61837416823BF5CE3FA93D8777DC9F9488F8877873CF2D26C54E4C3082569DD4DF7101AE3A9DAEBE891B10F803F867EE3470B9209B677219AF8B6CB5833EEF9F8C9532D57A7DC82AD6AA7590D9F4158C526544C7BFDAAFB8C3F1684ABEEF825A95D1E70744A8F72C00F0B3D27E6217469F66C9786B1C04DAE6E0AD3BD980CF1D51316D583DFBDCA15529BD5CB7C69AD48B4731D6E8787D8A27A5F194E439B6D253E9E4FF76D89C26614D93441EC0B4195E0B44AD02C297598C98BE474EA102198C10202E707B11D500F747C8A0F6D51F4035CD2AF54F4CB6FDF2BDC827FAD8649E903436634DDF002389B99CDD8968C2CBD91B0BB4BA648A1698912B0C29250CD060E08A55C854EA25F948424DD028527ABF880DDF29AB8DE742303B7818BC3F145747FF496BDB79FC7625E341E96B434531FC4E0171E32875E6DA92CBAA8816BA05A8D96D15314A0AE61A440F67F880E87896E3FF45E27551A8ED2F8C19E33B690F8CD600F4366488B386261B6D5D2534378056891C8F0218D26EE1160A027AB18D9BA0189CB3EA682EDEF04FAA68E85EF585BE0250FCEE8E55845F2AA737D7BFF36ECE44410E4CDE4B283740008D7E2B93E4211D0F59B56351937B2EF653401762C8A89CAD446EF0B0D6828F69FF3F57FDDBFF7B6422D838959DB5C4988201549394ABFCDEB44E3BB76A7E359CD3DE81E52D0F24DFEEFEDE99397227B48C192DDF6F3883E6360FACDB3A93FE8048F917CC0B7272682A836ED1BCA87DB7114E8ACCDA617C366B7ED3C77F6367B86C7CA84F26354C8CACB09A2584878A5FA6BC6CA2C8E6BD6E05C3F2DEAAF7452CC7AC97F96CDF8A147FF743FFF0CA3EB21D84BC57957EAB721FCEAA739DE8588463188BFFE75AEE8A0536AF32755F6EF06CCF12B28BC83B696A4D4713C4416CB0AC478276EC221BAEC53C05B6CDB9BAD541923C8F308EABED085C925583CBBFC527EB45B0E9F29073183F19F2B85B962F1CB38DBA4DFAD5C8AC49D07ED82338AF61508285BC5DB90C325AD6A3040651D0B8FC6563833DDD28992B495A27DDB0BE250A69155E830328E16E072D98BC82BF30410E8E70B43E8DE50DA3DB06F4F1998543368B67143D317525A9CD89990CFAECFC042DFD3A93510B5A8E7BADA30732C34A23ED94E70266CDC9986D425" ) ) ) );
|
||||
|
||||
|
||||
|
||||
// String base64 = "4D4949473877594B4B6F45637A315547415151434136434342754D7767676266416745414D5948344D494831416745414D4755775844454C4D416B474131554542684D43513034784D44417542674E5642416F4D4A304E6F6157356849455A70626D467559326C68624342445A584A3061575A7059324630615739754945463164476876636D6C30655445624D426B47413155454177775351305A445153425552564E5549464E4E4D694250513045784167555153594D554754414E42676B7167527A50565147434C514D46414152364D4867434946455735664A594536384E4945426B53355637664B3665614F6E6F65374F755854797A6E694F63304D4E6C41694176316F714641714C584144396875364C6F31336C687772493451485061494C34707554396E4674477433775167516E455039746D305348667A612F655751314532547A6770505258654278304374593374666C5547515455454548487964527073573163474142782F332B70686C6B55776767586442676F7167527A5056515942424149424D42734742797142484D395641576745454471374D2F563670654C5556445A37364C4D6478386541676757777265787950556A6A34644565666478554230496F504A69695368416547634C4E6661365A37556D646649752B36323437386F72575067446F49546B2F556C4336484964545661325270713334714C695A37724B7574786E743546473269425651323175414D736C39704D422F52306D593647593052387258417137424441476A7352746449366E37416A4237544A736A4C46736A554A3559343943713038684F6C54776E4239527663316E6378694973616443694A5831535650486C7A52316F57703949773475354A776D717A4350317139764A76423179436C654D464670537239646736526476687A4544653943766659332B4D444B442F70394A66742F4B466135587361633571515047524C70357747567758616675424C384B744D726D2F7278335231434B6C646644494F734A4C714D68386554617A4E7466443745362B49352B552B4E5336474B456941416E4A56794E3457614169337634624D78464F337A6B693775386A317A764E76427365387356463932522F36724133527A305866456C6844492B376E696A553273734C354F6264345753414F6A6D7950596F31697766326F646A4B434545655A6C31626D3331316C78616A596F332F34367569527554422F4A2F5349733750775945717952565651303662756D79694359503075354947305654323249526F69366D62744E4542764D48694E7A5779526443626E63614554314A4655324A4745487852435234626E7267442B694C6A5A6A5854634B453635706B58536635773335393453355050766F4E4A6F627835437279595650334266794131657566";
|
||||
// System.out.println( Util.bytes2HexString( Util.decodeBase64( new String( Util.hexString2Bytes( base64 ) ) ) ) );
|
||||
|
||||
|
||||
write("./cms.p7", new byte[2]);
|
||||
|
||||
String dm1 = read("/dm/dm1.p7");
|
||||
System.out.println("dm1.base64=" + dm1);
|
||||
byte[] dm = Util.decodeBase64( dm1 );
|
||||
System.out.println("dm1.hex=" + Util.bytes2HexString( dm ) );
|
||||
|
||||
// CMSEnvelopedData cms = SydCmsUtil.getCMSEnvelopedData( dm );
|
||||
// System.out.println( cms );
|
||||
|
||||
|
||||
ContentInfo info = SydCmsUtil.getContentInfo( dm );
|
||||
System.out.println( info );
|
||||
|
||||
byte[] test = new byte[ 20 * 1024 * 1024 ];
|
||||
Arrays.fill( test, (byte) 0x0F );
|
||||
Map<String,String>map = new HashMap<>();
|
||||
map.put("C", "CN");
|
||||
map.put("O", "组织");
|
||||
map.put("CN", "不知道");
|
||||
|
||||
// update( info , test, test, map);
|
||||
|
||||
byte[] dm2 = info.getEncoded();
|
||||
System.out.println( Util.bytes2HexString( dm2 ) );
|
||||
ContentInfo info2 = SydCmsUtil.getContentInfo( dm );
|
||||
System.out.println( info2 );
|
||||
|
||||
// System.out.println( dn8010() );
|
||||
//
|
||||
//
|
||||
// System.out.println(
|
||||
//
|
||||
// new String( Util.hexString2Bytes( "433D434E2C4F3D43464341204F4341312C4F553D594343412C4F553D496E646976696475616C2D322C434E3D5943434140BBC6BDF0BDBBD2D7CBF9405A6875616E676A4031" ) , "GBK")
|
||||
// );
|
||||
|
||||
// PKCS7Util.openEnvelope( );
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
package com.chakracoin.shsm.test;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.Provider;
|
||||
import java.security.Security;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.bouncycastle.asn1.cms.ContentInfo;
|
||||
import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.jcajce.JcaCertStore;
|
||||
import org.bouncycastle.cms.*;
|
||||
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
|
||||
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
|
||||
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
|
||||
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
|
||||
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
|
||||
import org.bouncycastle.util.Store;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
|
||||
import static org.bouncycastle.asn1.ASN1Encoding.DL;
|
||||
|
||||
public class PKCS7Util extends GMBaseTest {
|
||||
public PKCS7Util() {
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
}
|
||||
|
||||
|
||||
private static String ksType = "PKCS12";
|
||||
|
||||
/**
|
||||
* 生成数字签名
|
||||
* @param srcMsg 源信息
|
||||
* @param charSet 字符编码
|
||||
* @param certPath 证书路径
|
||||
* @param certPwd 证书密码
|
||||
* @return
|
||||
*/
|
||||
public static byte[] signMessage(String srcMsg, String charSet, String certPath, String certPwd) {
|
||||
String priKeyName = null;
|
||||
char passphrase[] = certPwd.toCharArray();
|
||||
|
||||
try {
|
||||
Provider provider = new BouncyCastleProvider();
|
||||
// 添加BouncyCastle作为安全提供
|
||||
Security.addProvider(provider);
|
||||
|
||||
// 加载证书
|
||||
KeyStore ks = KeyStore.getInstance(ksType);
|
||||
ks.load(new FileInputStream(certPath), passphrase);
|
||||
|
||||
if (ks.aliases().hasMoreElements()) {
|
||||
priKeyName = ks.aliases().nextElement();
|
||||
}
|
||||
|
||||
Certificate cert = (Certificate) ks.getCertificate(priKeyName);
|
||||
|
||||
// 获取私钥
|
||||
PrivateKey prikey = (PrivateKey) ks.getKey(priKeyName, passphrase);
|
||||
|
||||
X509Certificate cerx509 = (X509Certificate) cert;
|
||||
|
||||
List<Certificate> certList = new ArrayList<Certificate>();
|
||||
certList.add(cerx509);
|
||||
|
||||
CMSTypedData msg = (CMSTypedData) new CMSProcessableByteArray(
|
||||
srcMsg.getBytes(charSet));
|
||||
|
||||
Store certs = new JcaCertStore(certList);
|
||||
|
||||
CMSSignedDataGenerator gen = new CMSSignedDataGenerator();
|
||||
ContentSigner sha1Signer = new JcaContentSignerBuilder(
|
||||
"SHA1withRSA").setProvider("BC").build(prikey);
|
||||
|
||||
gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(
|
||||
new JcaDigestCalculatorProviderBuilder().setProvider("BC")
|
||||
.build()).build(sha1Signer, cerx509));
|
||||
|
||||
gen.addCertificates(certs);
|
||||
|
||||
CMSSignedData sigData = gen.generate(msg, true);
|
||||
|
||||
return Base64.encode(sigData.getEncoded());
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证数字签名
|
||||
* @param signedData
|
||||
* @return
|
||||
*/
|
||||
public static boolean signedDataVerify(byte[] signedData) {
|
||||
boolean verifyRet = true;
|
||||
try {
|
||||
// 新建PKCS#7签名数据处理对象
|
||||
CMSSignedData sign = new CMSSignedData(signedData);
|
||||
|
||||
// 添加BouncyCastle作为安全提供
|
||||
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
|
||||
// 获得证书信息
|
||||
Store certs = sign.getCertificates();
|
||||
|
||||
// 获得签名者信息
|
||||
SignerInformationStore signers = sign.getSignerInfos();
|
||||
Collection c = signers.getSigners();
|
||||
Iterator it = c.iterator();
|
||||
|
||||
// 当有多个签名者信息时需要全部验证
|
||||
while (it.hasNext()) {
|
||||
SignerInformation signer = (SignerInformation) it.next();
|
||||
|
||||
// 证书链
|
||||
Collection certCollection = certs.getMatches(signer.getSID());
|
||||
Iterator certIt = certCollection.iterator();
|
||||
X509CertificateHolder cert = (X509CertificateHolder) certIt
|
||||
.next();
|
||||
|
||||
// 验证数字签名
|
||||
if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder()
|
||||
.setProvider("BC").build(cert))) {
|
||||
verifyRet = true;
|
||||
} else {
|
||||
verifyRet = false;
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
verifyRet = false;
|
||||
e.printStackTrace();
|
||||
System.out.println("验证数字签名失败");
|
||||
}
|
||||
return verifyRet;
|
||||
}
|
||||
|
||||
/**
|
||||
* 加密数据
|
||||
* @param srcMsg 源信息
|
||||
* @param certPath 证书路径
|
||||
* @param charSet 字符编码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String envelopeMessage(String srcMsg, String certPath, String charSet) throws Exception {
|
||||
CertificateFactory certificatefactory;
|
||||
X509Certificate cert;
|
||||
// 使用公钥对对称密钥进行加密 //若此处不加参数 "BC" 会报异常:CertificateException -
|
||||
certificatefactory = CertificateFactory.getInstance("X.509", "BC");
|
||||
// 读取.crt文件;你可以读取绝对路径文件下的crt,返回一个InputStream(或其子类)即可。
|
||||
InputStream bais = new FileInputStream(certPath);
|
||||
|
||||
cert = (X509Certificate) certificatefactory.generateCertificate(bais);
|
||||
|
||||
//添加数字信封
|
||||
CMSTypedData msg = new CMSProcessableByteArray(srcMsg.getBytes(charSet));
|
||||
|
||||
CMSEnvelopedDataGenerator edGen = new CMSEnvelopedDataGenerator();
|
||||
|
||||
edGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(
|
||||
cert).setProvider("BC"));
|
||||
|
||||
CMSEnvelopedData ed = edGen.generate(msg,
|
||||
new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC)
|
||||
.setProvider("BC").build());
|
||||
|
||||
ContentInfo info = ed.toASN1Structure();
|
||||
|
||||
String rslt = new String(Base64.encode(info.getEncoded( DL )));
|
||||
|
||||
System.out.println(rslt);
|
||||
return rslt;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解密数据
|
||||
* @param encode 加密后的密文
|
||||
* @param certPath 证书路径
|
||||
* @param certPwd 证书密码
|
||||
* @param charSet 字符编码
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public static String openEnvelope(String encode, String certPath, String certPwd, String charSet) throws Exception {
|
||||
//获取密文
|
||||
CMSEnvelopedData ed = new CMSEnvelopedData(Base64.decode(encode.getBytes()));
|
||||
|
||||
RecipientInformationStore recipients = ed.getRecipientInfos();
|
||||
|
||||
Collection c = recipients.getRecipients();
|
||||
Iterator it = c.iterator();
|
||||
|
||||
// 加载证书
|
||||
KeyStore ks = KeyStore.getInstance(ksType);
|
||||
ks.load(new FileInputStream(certPath), certPwd.toCharArray());
|
||||
|
||||
String priKeyName = null;
|
||||
if (ks.aliases().hasMoreElements()) {
|
||||
priKeyName = ks.aliases().nextElement();
|
||||
}
|
||||
|
||||
// 获取私钥
|
||||
PrivateKey prikey = (PrivateKey) ks.getKey(priKeyName, certPwd.toCharArray());
|
||||
|
||||
byte[] recData = null;
|
||||
|
||||
//解密
|
||||
if (it.hasNext()) {
|
||||
RecipientInformation recipient = (RecipientInformation) it.next();
|
||||
|
||||
recData = recipient.getContent(new JceKeyTransEnvelopedRecipient(
|
||||
prikey).setProvider("BC"));
|
||||
}
|
||||
|
||||
return new String(recData, charSet);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.chakracoin.shsm.test;
|
||||
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
|
||||
// Bouncycastle pkcs5PBKDF2
|
||||
public class PKKDF2Test {
|
||||
public static void main(String[] args) throws NoSuchAlgorithmException, InvalidKeySpecException {
|
||||
|
||||
String key = PBKDF2Tool.gen("11111111", "B88480FD1ED2DC09", 2048, 8 );
|
||||
System.out.println( key );
|
||||
|
||||
|
||||
// "89 66 71 6C AD 2B F8 11 A6 43 3E ED F0 83 39 41 52 EB 42 87 8B 17 32 83 0E B2 F5 E9 BD 8E 5B AB 91 B8 81 05 54 C9 F4 87 5E C7 BE E7 5B 17 3D 95 F2 E0 55 D2 D8 62 3C 83 19 C6 E4 A3 DE D9 3A 6E 00 8B 43 19 C1 CE 22 69 EF D2 43 F5 8F 2C 11 0C 9B 53 61 F6 A6 05 B1 CF CF 40 64 01 48 41 FE 20 2D 3B CA 02 4F 9C 07 C5 E6 89 24 F8 BF 7F 9E 03 AD FC AA 91 6D FF E5 55 83 B1 8D 8C 99 AE 81 ED 0F F9 8B 27 27 93 B0 81 87 74 A3 31 6D 45 DB FE ";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.chakracoin.shsm.test;
|
||||
|
||||
import com.chakracoin.shsm.logiclayer.SM2Util;
|
||||
import org.bouncycastle.crypto.AsymmetricCipherKeyPair;
|
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.openssl.PEMWriter;
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
||||
|
||||
import java.io.*;
|
||||
import java.security.KeyPair;
|
||||
import java.security.Security;
|
||||
|
||||
public class SM2KeyUtilTest {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
AsymmetricCipherKeyPair keyPair = SM2Util.generateKeyPairParameter();
|
||||
ECPrivateKeyParameters priKey = (ECPrivateKeyParameters) keyPair.getPrivate();
|
||||
ECPublicKeyParameters pubKey = (ECPublicKeyParameters) keyPair.getPublic();
|
||||
|
||||
String der = privateKeyToDER(priKey);
|
||||
|
||||
System.out.println( der );
|
||||
|
||||
// SO22963581BCPEMPrivateEC();
|
||||
}
|
||||
|
||||
/**
|
||||
* 仅支持国密标准 SM2 密钥
|
||||
* 便利法门,并不严谨
|
||||
* @param priKey
|
||||
*/
|
||||
static String privateKeyToDER(ECPrivateKeyParameters priKey ){
|
||||
String hex = priKey.getD().toString(16);
|
||||
return privateKeyToDer( hex );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 仅支持国密标准 SM2 密钥
|
||||
* 便利法门,并不严谨
|
||||
* @param hexKey 长度 64
|
||||
* @return
|
||||
*/
|
||||
static String privateKeyToDer(String hexKey){
|
||||
|
||||
|
||||
final String head = "-----BEGIN EC PARAMETERS-----\n" +
|
||||
"BggqgRzPVQGCLQ==\n" +
|
||||
"-----END EC PARAMETERS-----\n" +
|
||||
"-----BEGIN EC PRIVATE KEY-----\n";
|
||||
|
||||
final String tail = "\n-----END EC PRIVATE KEY-----";
|
||||
|
||||
return head + "30310201010420" + hexKey + "a00a06082a811ccf5501822d" + tail;
|
||||
}
|
||||
|
||||
|
||||
// static void SO22963581BCPEMPrivateEC() throws Exception {
|
||||
// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
// Reader rdr = new StringReader( );
|
||||
// Object parsed = new org.bouncycastle.openssl.PEMParser(rdr).readObject();
|
||||
// KeyPair pair = new org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter().getKeyPair((org.bouncycastle.openssl.PEMKeyPair) parsed);
|
||||
// System.out.println(pair.getPrivate().getAlgorithm());
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
//package com.chakracoin.shsm.test;
|
||||
//
|
||||
//import org.bouncycastle.cms.*;
|
||||
//import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
|
||||
//import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
|
||||
//import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
//import org.bouncycastle.operator.OutputEncryptor;
|
||||
//import org.bouncycastle.util.io.pem.PemObject;
|
||||
//import org.bouncycastle.util.io.pem.PemReader;
|
||||
//
|
||||
//import javax.crypto.*;
|
||||
//import java.io.*;
|
||||
//import java.security.*;
|
||||
//import java.security.cert.CertificateEncodingException;
|
||||
//import java.security.cert.CertificateException;
|
||||
//import java.security.cert.CertificateFactory;
|
||||
//import java.security.cert.X509Certificate;
|
||||
//
|
||||
//public class PKCS7EnvelopExample {
|
||||
// public static void main(String[] args) {
|
||||
// Security.addProvider(new BouncyCastleProvider());
|
||||
//
|
||||
// try {
|
||||
// // 读取RSA公钥证书
|
||||
// X509Certificate recipientCert = readCertificate("public_key.pem");
|
||||
//
|
||||
// // 生成对称密钥
|
||||
// KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
// keyGenerator.init(256); // 使用256位密钥
|
||||
// SecretKey symmetricKey = keyGenerator.generateKey();
|
||||
//
|
||||
// // 加密明文
|
||||
// byte[] plaintext = "Hello, World!".getBytes();
|
||||
// byte[] ciphertext = encryptWithAES(plaintext, symmetricKey);
|
||||
//
|
||||
// // 创建PKCS7数字信封
|
||||
// byte[] envelope = createPKCS7Envelope(ciphertext, symmetricKey, recipientCert);
|
||||
//
|
||||
// // 保存PKCS7数字信封到文件
|
||||
// FileOutputStream fileOutputStream = new FileOutputStream("envelope.p7");
|
||||
// fileOutputStream.write(envelope);
|
||||
// fileOutputStream.close();
|
||||
//
|
||||
// System.out.println("PKCS7 envelope created successfully.");
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private static X509Certificate readCertificate(String filePath) throws IOException, CertificateException {
|
||||
// FileInputStream fileInputStream = new FileInputStream(filePath);
|
||||
// CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
// X509Certificate certificate = (X509Certificate) certificateFactory.generateCertificate(fileInputStream);
|
||||
// fileInputStream.close();
|
||||
// return certificate;
|
||||
// }
|
||||
//
|
||||
// private static byte[] encryptWithAES(byte[] plaintext, SecretKey symmetricKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, NoSuchPaddingException, IllegalBlockSizeException {
|
||||
// Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
// cipher.init(Cipher.ENCRYPT_MODE, symmetricKey);
|
||||
// return cipher.doFinal(plaintext);
|
||||
// }
|
||||
//
|
||||
// private static byte[] createPKCS7Envelope(byte[] ciphertext, SecretKey symmetricKey, X509Certificate recipientCert) throws CertificateEncodingException, CMSException, IOException, OperatorCreationException, CertificateEncodingException {
|
||||
// CMSEnvelopedDataGenerator envelopedDataGenerator = new CMSEnvelopedDataGenerator();
|
||||
//
|
||||
// JceKeyTransRecipientInfoGenerator recipientInfoGenerator = new JceKeyTransRecipientInfoGenerator(recipientCert);
|
||||
// envelopedDataGenerator.addRecipientInfoGenerator(recipientInfoGenerator);
|
||||
//
|
||||
// CMSTypedData cmsTypedData = new CMSProcessableByteArray(ciphertext);
|
||||
//
|
||||
// OutputEncryptor outputEncryptor = new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES256_CBC).setProvider("BC").build();
|
||||
//
|
||||
// CMSEnvelopedData cmsEnvelopedData = envelopedDataGenerator.generate(cmsTypedData, outputEncryptor);
|
||||
//
|
||||
// return cmsEnvelopedData.getEncoded();
|
||||
// }
|
||||
//}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.chakracoin.shsm.test;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.Security;
|
||||
|
||||
public class t2 {
|
||||
|
||||
static {
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
public static void main(String[] args) throws Exception {
|
||||
PKCS7Util.envelopeMessage("1111", "D:\\docker\\nginx\\conf\\domain.crt", "utf-8");
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user