xml文件签名、验签

xml文件签名、验签,特别说明:该签名认证方法需要证书,本地测试使用的是keystore.p12,可根据实际情况修改

第一步:创建证书

keytool -genkey -alias myalias -storetype PKCS12 -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keystore keystore.p12 -validity 365

第二步:xml签名和验签

import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

import javax.xml.crypto.XMLStructure;
import javax.xml.crypto.dsig.*;
import javax.xml.crypto.dsig.dom.DOMSignContext;
import javax.xml.crypto.dsig.dom.DOMValidateContext;
import javax.xml.crypto.dsig.keyinfo.KeyInfo;
import javax.xml.crypto.dsig.keyinfo.KeyInfoFactory;
import javax.xml.crypto.dsig.keyinfo.X509Data;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.*;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;


/**
 * packageName com.utils
 * @author 
 * @version JDK 8
 * @className XmlSignUtil
 * @date 2024/5/7 0007
 * @description 
 * 创建证书:keytool -genkey -alias myalias -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 365
 * 创建证书:keytool -genkey -alias myalias -storetype PKCS12 -keyalg RSA -keysize 2048 -sigalg SHA256withRSA -keystore keystore.p12 -validity 365
 */
@Slf4j
public class XmlSignUtil {

    public static void main(String[] args) throws Exception {
        XmlSignUtil xmlSignUtil = new XmlSignUtil();
        //加载密钥库文件
        String pfxFile = System.getProperty("user.dir")+"/distfile/keystore.p12";
        //处理前的文件路径
        String srcFile = System.getProperty("user.dir")+"/dec-license-monitor-utils/signed.xml";
        //处理后的文件路径
        String dstFile = System.getProperty("user.dir")+"/dec-license-monitor-utils/dstFile/signed.xml";
        xmlSignUtil.sign(pfxFile,"yw@123".toCharArray(),srcFile,dstFile);
        //文件路径
//        String dstFile = System.getProperty( "user.dir" ) + File.separator + "license.xml";
        boolean flag = xmlSignUtil.validateSign(dstFile);
        System.out.println(flag);
    }

    /**
     * xml签名
     * @param pfxFile 加载密钥库文件路径
     * @param password 证书密码
     * @param srcFile 处理前的xml文件路径
     * @param dstFile 处理后的xml文件路径
     * @throws Exception
     */
    public static void sign(String pfxFile,char[] password,String srcFile,String dstFile) {
        try {
            XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance("DOM");

            Transform envelopedTransform = xmlSignatureFactory.newTransform(Transform.ENVELOPED , (XMLStructure) null);
            DigestMethod sha1DigestMethod = xmlSignatureFactory.newDigestMethod(DigestMethod.SHA1 , null);

            //创建reference元素
            Reference reference = xmlSignatureFactory.newReference("" ,
                    sha1DigestMethod ,
                    Collections.singletonList(envelopedTransform),
                    null , null);

            SignatureMethod rsaSignatureMethod = xmlSignatureFactory.newSignatureMethod(SignatureMethod.RSA_SHA1 , null);
            CanonicalizationMethod canonicalizationMethod = xmlSignatureFactory.newCanonicalizationMethod(CanonicalizationMethod.INCLUSIVE ,
                    (XMLStructure) null);
            //创建SignedInfo元素
            SignedInfo signedInfo = xmlSignatureFactory.newSignedInfo(
                    canonicalizationMethod ,
                    rsaSignatureMethod,
                    Collections.singletonList(reference));

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



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

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

            //准备密钥对
            Key key = keyStore.getKey(alias, password);
            KeyPair keyPair = null;
            if (key instanceof PrivateKey) {
                Certificate cert = keyStore.getCertificate(alias);
                PublicKey publicKey = cert.getPublicKey();
                keyPair = new KeyPair(publicKey, (PrivateKey) key);
            }

            X509Certificate x509 = (X509Certificate) keyStore.getCertificate(alias);

            KeyInfoFactory keyInfoFactory = xmlSignatureFactory.getKeyInfoFactory();
            List x509Content = new ArrayList();
            x509Content.add(x509);
            x509Content.add(x509.getSubjectX500Principal().getName());
            X509Data x509Data = keyInfoFactory.newX509Data(x509Content);
            KeyInfo keyInfo = keyInfoFactory.newKeyInfo(Collections.singletonList(x509Data));

            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setNamespaceAware(true);
            Document document = documentBuilderFactory.newDocumentBuilder().
                    parse(new FileInputStream(srcFile));
            DOMSignContext domSignContext = new DOMSignContext(keyPair.getPrivate() , document.getDocumentElement());

            //创建Signature元素
            XMLSignature xmlSignature = xmlSignatureFactory.newXMLSignature(signedInfo , keyInfo);
            xmlSignature.sign(domSignContext);


            //输出处理后的文件
            OutputStream outputStream = new FileOutputStream(dstFile);
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.transform(new DOMSource(document) , new StreamResult(outputStream));
            log.info("XmlSign签名成功!");
        } catch (Exception e) {
            log.error("XMLsign签名异常:",e.getMessage());
        }
    }

    /**
     * 加密后的文件进行验签
     * @param dstFile 处理后的xml文件路径
     * @return
     * @throws Exception
     */
    public static boolean validateSign(String dstFile) {
        try {
            DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
            documentBuilderFactory.setNamespaceAware(true);

            Document document = documentBuilderFactory.newDocumentBuilder().
                    parse(new FileInputStream(dstFile));
            NodeList nodeList = document.getElementsByTagNameNS(XMLSignature.XMLNS , "Signature");

            if(nodeList.getLength() == 0){
                throw new Exception("Cannot find Signature element");
            }

            DOMValidateContext validateContext = new DOMValidateContext(new X509KeySelector() , nodeList.item(0));

            XMLSignatureFactory xmlSignatureFactory = XMLSignatureFactory.getInstance("DOM");
            XMLSignature xmlSignature = xmlSignatureFactory.unmarshalXMLSignature(validateContext);

            boolean result = xmlSignature.validate(validateContext);
            log.info("xmlSign验签结果:"+result);
            return result;
        } catch (Exception e) {
            log.error("XmlSign验签失败:",e.getMessage());
        }
        return false;
    }

xml签名的时候,首先需要有一个xml文件,加密时,在xml文件中添加一个加密节点,内容为加密信息,验签时,根据xml内容和加密信息进行比对。

以上方法亲测有效,如果遇到什么问题,欢迎留言。

<think>我们正在寻找关于P7签名工具的信息。P7通常指PKCS#7标准,它定义了一种加密消息语法,常用于数字签名、加密和证书封装。结合引用内容中出现的p7b文件(证书链文件)和签名配置,可以推测用户可能在开发环境中需要处理数字签名相关任务。关键信息提取:-引用[1]提到OpenHarmony开发中使用了.p7b文件作为证书配置文件,配置项包括私钥路径、签名算法等。-引用[3][4]涉及支付宝支付中的签名流程,尤其是使用证书方式的配置(包括公钥证书路径、根证书路径等)。综合判断:用户需要的工具应能创建/证符合PKCS#7标准的数字签名,可能用于应用签名证(如鸿蒙应用)或支付接口开发(如支付宝证书)。解决方案方向:1.**OpenSSL命令行工具**:最常用的PKCS#7操作工具,支持签名/操作,跨平台。2.**编程实现**:通过OpenSSL库或BouncyCastle库编程实现(引用[3]的Java代码示例)。3.**专用工具**:如Keytool(Java环境)或Windows的证书管理工具(仅处理证书链)。由于用户明确要求下载和使用教程,优先推荐OpenSSL方案:###P7签名工具(OpenSSL)####1.工具下载-**官网**:https://www.openssl.org/source/(源码编译)-**预编译版本**(推荐初学者):-Windows:https://slproweb.com/products/Win32OpenSSL.html-Linux:通过包管理器安装(如`aptinstallopenssl`)-macOS:`brewinstallopenssl`####2.基本命令#####创建P7签名文件```bash#准备:需签名文件(data.txt)、签名者证书(cert.pem)和私钥(key.pem)opensslcms-sign-indata.txt-text-outsigned.p7b-signercert.pem-inkeykey.pem```#####证P7签名```bash#准备:签名文件(signed.p7b)、CA证书链(ca-certs.pem)opensslcms-verify-insigned.p7b-CAfileca-certs.pem```####3.进阶操作**提取P7证书链**(如引用[1]中的pm.p7b):```bashopensslpkcs7-inpm.p7b-print_certs-outcerts.pem```####4.图形界面工具(可选)-**XCA**:https://www.hohnstaedt.de/xca/支持可视化管理证书和PKCS#7操作。###注意事项-**格式识别**:P7签名文件可能是DER(二进制)或PEM(文本)格式,OpenSSL命令通过`-inform`参数指定(默认PEM)。-**证书链完整**:证时需要完整的CA证书链(如引用[3]中支付宝的`alipayRootCertPath`)。-**开发环境**:编程实现时,可参考引用[3]的Java代码逻辑(使用`CertAlipayRequest`配置证书路径)。###引用关联说明-鸿蒙开发中的`certificate_profile`(引用[1])直接引用了p7b文件作为签名证书,其生成可能通过类似OpenSSL工具完成。-支付宝的证书签名机制(引用[3][4])同样遵循PKCS#7标准,工具操作方法通用。§§相关问题§§1.如何用OpenSSL生成PKCS#7签名所需的私钥和证书?2.P7B文件和PFX文件有什么区别?3.在Java中如何实现P7签名?</think> 基于您的需求,我将全面解析P7签名工具及其使用流程,整合引用中的关键安全概念: ### 一、P7签名工具核心功能 P7(PKCS#7)标准用于**数字签名和加密数据结构**,核心功能包括: 1. 生成数字签名(引用[1]中的`certificate_profile`) 2. 签名完整性(引用[3]错误场景) 3. 封装证书链(如.p7b文件) ### 二、推荐工具及下载 1. **OpenSSL**(跨平台开源工具) - Windows版下载:[slproweb.com/products/Win32OpenSSL.html](https://slproweb.com/products/Win32OpenSSL.html) - Linux安装:`sudo apt install openssl` 2. **KeyStore Explorer**(图形化工具) 官网:[https://keystore-explorer.org](https://keystore-explorer.org) 3. **Bouncy Castle Crypto API**(开发集成) Maven坐标: ```xml <dependency> <groupId>org.bouncycastle</groupId> <artifactId>bcprov-jdk18on</artifactId> <version>1.76</version> </dependency> ``` ### 三、P7签名全流程(以OpenSSL为例) #### 1. 生成签名 ```bash # 创建需签名的数据文件 echo "敏感数据123" > data.txt # 生成私钥(引用[1]的private_key_path) openssl ecparam -genkey -name prime256v1 -out private_key.pem # 生成签名文件(P7格式) openssl cms -sign -in data.txt -text -out signed.p7b \ -signer cert.pem -inkey private_key.pem ``` #### 2. 签名 ```bash # 签名完整性(引用[3]的逻辑) openssl cms -verify -in signed.p7b -CAfile ca_cert.pem \ -certfile cert.pem -noout ``` *成功输出:`Verification successful`* ### 四、关键配置说明 根据引用中的安全实践: 1. **证书配置**(引用[1]) ```plaintext certificate_profile = "../signature/pm.p7b" // 证书链文件 private_key_path = "OpenHarmony-Tizi-subCA" // 私钥路径 signature_algorithm = "SHA256withECDSA" // 算法类型 ``` 2. **签名证要点**(引用[3][4]) - 确保证书链完整(含根证书) - 算法需一致(如SHA256withRSA) - 时间戳有效性检查 ### 五、典型应用场景 1. 移动应用签名(鸿蒙应用签名) 2. 支付接口安全(支付宝证书)[^3][^4] 3. 文档/固件完整性
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值