非对称签名验签
This commit is contained in:
parent
61f94f39cb
commit
81b0ea4c3b
@ -11,45 +11,49 @@ import com.sunyard.chsm.mapper.SpKeyRecordMapper;
|
||||
import com.sunyard.chsm.model.entity.AppCert;
|
||||
import com.sunyard.chsm.model.entity.KeyInfo;
|
||||
import com.sunyard.chsm.model.entity.KeyRecord;
|
||||
import com.sunyard.chsm.param.AsymDecryptReq;
|
||||
import com.sunyard.chsm.param.AsymDecryptResp;
|
||||
import com.sunyard.chsm.param.AsymEncryptReq;
|
||||
import com.sunyard.chsm.param.AsymEncryptResp;
|
||||
import com.sunyard.chsm.param.AsymSignP7Req;
|
||||
import com.sunyard.chsm.param.AsymSignP7Resp;
|
||||
import com.sunyard.chsm.param.AsymSignRawReq;
|
||||
import com.sunyard.chsm.param.AsymSignRawResp;
|
||||
import com.sunyard.chsm.param.AsymVerifyP7Req;
|
||||
import com.sunyard.chsm.param.AsymVerifyRawReq;
|
||||
import com.sunyard.chsm.param.VerifyResp;
|
||||
import com.sunyard.chsm.param.*;
|
||||
import com.sunyard.chsm.sdf.SdfApiService;
|
||||
import com.sunyard.chsm.sdf.model.EccCipher;
|
||||
import com.sunyard.chsm.sdf.model.EccSignature;
|
||||
import com.sunyard.chsm.utils.CodecUtils;
|
||||
import com.sunyard.chsm.utils.gm.BCECUtils;
|
||||
import com.sunyard.chsm.utils.gm.BCSM2Utils;
|
||||
import com.sunyard.chsm.utils.gm.BCSM4Utils;
|
||||
import com.sunyard.chsm.utils.gm.cert.BCSM2CertUtils;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
|
||||
import org.bouncycastle.asn1.DERNull;
|
||||
import org.bouncycastle.asn1.DEROctetString;
|
||||
import org.bouncycastle.asn1.DERSet;
|
||||
import org.bouncycastle.asn1.cms.*;
|
||||
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.jcajce.JcaCertStore;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.cms.CMSProcessableByteArray;
|
||||
import org.bouncycastle.cms.CMSSignedData;
|
||||
import org.bouncycastle.cms.CMSSignedDataGenerator;
|
||||
import org.bouncycastle.cms.CMSTypedData;
|
||||
import org.bouncycastle.cms.SignerInfoGenerator;
|
||||
import org.bouncycastle.cms.SignerInformation;
|
||||
import org.bouncycastle.cms.SignerInformationStore;
|
||||
import org.bouncycastle.cms.*;
|
||||
import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;
|
||||
import org.bouncycastle.cms.jcajce.JcaSignerInfoVerifierBuilder;
|
||||
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
|
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.bouncycastle.jcajce.io.CipherInputStream;
|
||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
|
||||
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.operator.InputDecryptor;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
|
||||
import org.bouncycastle.util.Store;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.io.InputStream;
|
||||
import java.security.Key;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Collection;
|
||||
@ -235,7 +239,7 @@ public class AsymKeyService {
|
||||
return resp;
|
||||
}
|
||||
|
||||
private static byte[] p7Sign(byte[] pri, String cert, byte[] plainData, boolean encapsulate) {
|
||||
private byte[] p7Sign(byte[] pri, String cert, byte[] plainData, boolean encapsulate) {
|
||||
try {
|
||||
BCECPrivateKey privateKey = BCECUtils.createPrivateKey(pri);
|
||||
X509Certificate x509Cert = BCSM2CertUtils.getX509Cert(cert);
|
||||
@ -290,6 +294,81 @@ public class AsymKeyService {
|
||||
return false;
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private byte[] makeEnvelopeData(byte[] srcMsg, byte[] certData) {
|
||||
X509Certificate cert = BCSM2CertUtils.getX509Certificate(certData);
|
||||
AlgorithmIdentifier symAlg = new AlgorithmIdentifier(GMObjectIdentifiers.sm_scheme.branch("104")); // sm4
|
||||
AlgorithmIdentifier asymAlg = new AlgorithmIdentifier(GMObjectIdentifiers.sm2encrypt, DERNull.INSTANCE);
|
||||
|
||||
byte[] symKey = sdfApiService.generateRandom(16);
|
||||
|
||||
BCECPublicKey publicKey = (BCECPublicKey) cert.getPublicKey();
|
||||
byte[] encryptKey = BCSM2Utils.encrypt(publicKey, symKey);
|
||||
|
||||
X500Name x500Name = X500Name.getInstance(cert.getIssuerX500Principal().getEncoded());
|
||||
KeyTransRecipientInfo keyTransRecipientInfo = new KeyTransRecipientInfo(
|
||||
new RecipientIdentifier(new IssuerAndSerialNumber(x500Name, cert.getSerialNumber())),
|
||||
asymAlg,
|
||||
new DEROctetString(encryptKey)
|
||||
);
|
||||
|
||||
byte[] encContent = BCSM4Utils.encrypt_ECB_Padding(symKey, srcMsg);
|
||||
RecipientInfo recipientInfo = new RecipientInfo(keyTransRecipientInfo);
|
||||
EncryptedContentInfo encContentInfo = new EncryptedContentInfo(
|
||||
new ASN1ObjectIdentifier("1.2.156.10197.6.1.4.2.1"),
|
||||
symAlg,
|
||||
new DEROctetString(encContent)
|
||||
);
|
||||
EnvelopedData envelopedData = new EnvelopedData(null,
|
||||
new DERSet(recipientInfo),
|
||||
encContentInfo,
|
||||
(org.bouncycastle.asn1.ASN1Set) null);
|
||||
|
||||
ContentInfo contentInfo = new ContentInfo(new ASN1ObjectIdentifier("1.2.156.10197.6.1.4.2.3"), envelopedData);
|
||||
return contentInfo.getEncoded("DER");
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
private byte[] decryptEnvelopeData(byte[] envelopeData, byte[] priKeyD) {
|
||||
ECPrivateKeyParameters priKeyParameters = BCECUtils.createECPrivateKeyParameters(priKeyD);
|
||||
final BCECPrivateKey priKey = new BCECPrivateKey("EC", priKeyParameters, BouncyCastleProvider.CONFIGURATION);
|
||||
|
||||
// 解密数字信封
|
||||
CMSEnvelopedData ed = new CMSEnvelopedData(envelopeData);
|
||||
RecipientInformationStore recipientInfos = ed.getRecipientInfos();
|
||||
Collection<RecipientInformation> recipients = recipientInfos.getRecipients();
|
||||
RecipientInformation next = recipients.iterator().next();
|
||||
|
||||
return next.getContent(new JceKeyTransEnvelopedRecipient(priKey) {
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public RecipientOperator getRecipientOperator(AlgorithmIdentifier keyEncAlg,
|
||||
AlgorithmIdentifier contentEncryptionAlgorithm,
|
||||
byte[] encryptedContentKey) {
|
||||
String keyEncId = keyEncAlg.getAlgorithm().getId();
|
||||
if (Objects.equals(GMObjectIdentifiers.sm2encrypt.getId(), keyEncId)) {
|
||||
byte[] keyBytes = BCSM2Utils.decrypt(priKeyParameters, encryptedContentKey);
|
||||
Cipher cipher = Cipher.getInstance("SM4/ECB/PKCS7Padding", BouncyCastleProvider.PROVIDER_NAME);
|
||||
Key sm4Key = new SecretKeySpec(keyBytes, "SM4");
|
||||
cipher.init(Cipher.DECRYPT_MODE, sm4Key);
|
||||
return new RecipientOperator(new InputDecryptor() {
|
||||
@Override
|
||||
public AlgorithmIdentifier getAlgorithmIdentifier() {
|
||||
return contentEncryptionAlgorithm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getInputStream(InputStream dataIn) {
|
||||
return new CipherInputStream(dataIn, cipher);
|
||||
}
|
||||
});
|
||||
}
|
||||
return super.getRecipientOperator(keyEncAlg, contentEncryptionAlgorithm, encryptedContentKey);
|
||||
}
|
||||
}.setProvider(BouncyCastleProvider.PROVIDER_NAME));
|
||||
}
|
||||
|
||||
|
||||
private KeyInfo checkKey(Long keyId, KeyUsage usage) {
|
||||
|
||||
KeyInfo keyInfo = keyInfoMapper.selectById(keyId);
|
||||
|
Loading…
Reference in New Issue
Block a user