Pkcs7Detache 数字签名、验签

detache格式包中不包含明文信息。因此在验证的时候,还需要传递明文才能验证成功。同理,这里的明文实际上是真正内容的摘要。

实现步骤如下:

第一步:创建证书

生成keystore文件
keytool -genkey -alias ynhr -keyalg RSA -keysize 1024 -keypass yw@123 -validity 36500 -keystore test.keystore -storepass yw@123

导出私钥文件
keytool -importkeystore -srcstoretype JKS -srckeystore test.keystore -srcstorepass yw@123 -srcalias ynhr -srckeypass yw@123 -deststoretype PKCS12 -destkeystore keystore.p12 -deststorepass yw@123 -destalias client -destkeypass yw@123 -noprompt

第二步:加密和验签

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
import org.bouncycastle.cms.CMSProcessable;
import org.bouncycastle.cms.CMSSignedData;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.util.Store;

import java.io.File;
import java.io.FileInputStream;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.Base64;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Iterator;

/**
 * detache格式包中不包含明文信息。因此在验证的时候,还需要传递明文才能验证成功。同理,这里的明文        
    实际上是真正内容的摘要。
 * @author administrator
 * @version JDK 8
 * @className Pkcs7DetacheUtil
 * @date 2024/5/11 0011
 * @description Pkcs7Detache 数字签名、验签
 */
@Slf4j
public class Pkcs7DetacheUtil {

    /**
     * 加密算法
     */
    private static final String KEY_ALGORITHM = "SHA256withRSA";

    public static void main(String[] args) {
        String pfxFile = System.getProperty("user.dir")+"/keystore.p12";
        String password = "yw@123";
        String content = "你好";
        String signValue = Pkcs7DetacheUtil.signature(content,pfxFile,password);
        System.out.println(signValue);
        byte[] dataToSign = content.getBytes();
        boolean flag = Pkcs7DetacheUtil.verifySignature(dataToSign,Base64.getDecoder().decode(signValue),pfxFile,password);
        System.out.println(flag);
        
    }

    /**
     * 签名验证
     * @param data data是你的原始数据
     * @param signature signature是之前生成的PKCS#7格式的签名
     * @param pfxFile
     * @param password
     * @return
     */
    public static boolean verifySignature(byte[] data, byte[] signature,String pfxFile, String password) {
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

            //创建密钥对
            KeyStore keyStore = KeyStore.getInstance("PKCS12");

            File file = new File(pfxFile);
            FileInputStream fis = new FileInputStream(file);
            keyStore.load(fis, password.toCharArray());
            fis.close();

            //获取别名
            Enumeration enumas = keyStore.aliases();
            String alias = null;
            while (enumas.hasMoreElements()) {
                alias = (String) enumas.nextElement();
            }

            //准备密钥对
            Key key = keyStore.getKey(alias, password.toCharArray());
            PublicKey publicKey=null;
            if (key instanceof PrivateKey) {
                //获取用户证书
                Certificate cert = keyStore.getCertificate(alias);
                publicKey = cert.getPublicKey();
            }
            Signature sig = Signature.getInstance(KEY_ALGORITHM);
            // 使用私钥初始化 Signature 对象
            sig.initSign((PrivateKey) key);
            sig.update(data);
            // 使用公钥验证签名
            sig.initVerify(publicKey);
            sig.update(data);
            boolean isVerified = sig.verify(signature);
            log.info("Pkcs7Detach 验签结果:",isVerified);
            if (isVerified) {
                log.info("Pkcs7Detach 验签成功,返回为:",isVerified);
            }
            return isVerified;
        } catch (Exception e) {
            e.printStackTrace();
            log.error("Pkcs7Detach 验证失败:{}",e.getMessage());
        }
        return false;
    }

    /**
     * Pkcs7Detach 签名
     * @param content 内容
     * @param pfxFile 证书路径
     * @param password 证书密码
     * @return
     */
    public static String signature(String content,String pfxFile,String password){
        if (StringUtils.isEmpty(content)) {
            return "加密内容为空";
        }
        if (StringUtils.isEmpty(pfxFile)) {
            return "证书路径为空";
        }
        if (StringUtils.isEmpty(password)) {
            return "证书密码为空";
        }
        try {
            Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

            //创建密钥对
            KeyStore keyStore = KeyStore.getInstance("PKCS12");

            File file = new File(pfxFile);
            FileInputStream fis = new FileInputStream(file);
            keyStore.load(fis, password.toCharArray());
            fis.close();

            //获取别名
            Enumeration enumas = keyStore.aliases();
            String alias = null;
            while (enumas.hasMoreElements()) {
                alias = (String) enumas.nextElement();
            }

            //准备密钥对
            Key key = keyStore.getKey(alias, password.toCharArray());
            Signature sig = Signature.getInstance(KEY_ALGORITHM);
            // 使用私钥初始化 Signature 对象
            sig.initSign((PrivateKey) key);
            sig.update(content.getBytes());
            // 生成签名
            byte[] sign = sig.sign();
            log.info("Pkcs7Detach 签名成功,加密后的密文为:",Base64.getEncoder().encodeToString(sign));
            return Base64.getEncoder().encodeToString(sign);
        } catch (Exception e) {
            e.printStackTrace();
            log.error("Pkcs7Detach 签名异常:"+e.getMessage());
        }
        return null;
    }

}

Pkcs7Detache 只有签名和验签,没有解密的方法。如有任何问题欢迎留言。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值