CMS签名

进行CMS签名

使用Openssl命令行模拟华为公司签名平台的CMS签名,即执行openssl命令,创建根证书、二级CA签名证书、二级CA时间戳证书、签名证书和时间戳证书、证书吊销列表crl、CMS签名和时间戳签名,并使用cmssign工具合成符合华为公司签名平台的CMS签名和时间戳签名,最终完成类似华为签名平台的CMS签名,生产环境下,用户需妥善保管私钥。

使用Openssl生成证书只能用于开发和测试阶段,正式商用发布需要客户构建PKI系统或CA系统(用于管理密钥和证书)。当前提供的签名方式仅做参考,客户可以根据自身情况使用PKI系统并结合CMS格式进行签名,同时客户需要自行管理产生的密钥和证书。

本章节以对initrd.ini文件进行CMS签名为例,输入为initrd.ini文件,输出结果为initrd.ini.cms和initrd.ini.crl文件。

  1. 登录Linux服务器并执行如下命令切换至root用户。

    su - root

  2. 进入Linux服务器任意目录,比如/root/sign,在该目录下创建并编写以下配置文件。

    • 生成CA根证书。
      1. 执行vi x509_rootcaG1.cnf命令生成并编写x509_rootcaG1.cnf文件,将如下内容加入到该文件中。
        [ req ]
        default_bits = 4096
        distinguished_name = req_distinguished_name
        prompt = no
        string_mask = utf8only
        x509_extensions = extensions
        
        [ req_distinguished_name ]
        C = CN
        O = Test
        CN = RootCA G1
        #emailAddress = cmscbb@huawei.com
        
        [ extensions ]
        subjectKeyIdentifier = hash
        authorityKeyIdentifier = keyid:always, issuer
        basicConstraints = CA:TRUE
        keyUsage = cRLSign, keyCertSign

        执行:wq!保存该文件。

      2. 执行如下命令创建根证书。

        openssl req -new -nodes -utf8 -sha256 -days 36500 -batch -x509 -config x509_rootcaG1.cnf -outform PEM -out rootcaG1.pem -keyout rootca_priG1_pri.pem

        openssl x509 -in rootcaG1.pem -inform pem -outform der -out rootcaG1.der

    • 生成CA签名证书。
      1. 执行vi x509_signca.cnf命令生成并编写x509_signca.cnf文件,将如下内容加入到该文件中。
        [ req ]
        default_bits = 2048
        distinguished_name = req_distinguished_name
        prompt = no
        string_mask = utf8only
        x509_extensions = extensions
        
        [ req_distinguished_name ]
        C = CN
        O = Test
        CN = Signing Certificate CA G1
        #emailAddress = cmscbb@huawei.com
        
        [ extensions ]
        subjectKeyIdentifier = hash
        authorityKeyIdentifier = keyid, issuer
        basicConstraints = CA:TRUE
        keyUsage = cRLSign, keyCertSign
        extendedKeyUsage = codeSigning

        执行:wq!保存该文件。

      2. 执行如下命令创建根证书。

        openssl genrsa -out signca_pri.pem 3072

        openssl req -new -config x509_signca.cnf -out signca.csr -key signca_pri.pem

        openssl x509 -req -in signca.csr -CA rootcaG1.pem -CAkey rootca_priG1_pri.pem -CAcreateserial -out signca.pem -days 3650 -extensions extensions -extfile x509_signca.cnf

        openssl x509 -in signca.pem -inform pem -outform der -out signca.der

    • 生成CA时间戳证书。
      1. 执行vi x509_tsca.cnf命令生成并编写x509_tsca.cnf文件,将如下内容加入到该文件中。
        [ req ]
        default_bits = 4096
        distinguished_name = req_distinguished_name
        prompt = no
        string_mask = utf8only
        x509_extensions = extensions
        
        [ req_distinguished_name ]
        C = CN
        O = Test
        CN = Timestamp Certificate CA G1
        #emailAddress = cmscbb@huawei.com
        
        [ extensions ]
        subjectKeyIdentifier = hash
        authorityKeyIdentifier = keyid:always, issuer
        basicConstraints = CA:TRUE
        keyUsage = cRLSign, keyCertSign
        extendedKeyUsage = critical, timeStamping
        
        [ tsa ]
        default_tsa = tsa_config1
        
        [ tsa_config1 ]
        serial = ./serial
        crypto_device = builtin
        #certs = ./certs/tsa.pem
        signer_digest = sha256
        default_policy	= 1.2.3.4.1
        other_policies	= 1.2.3.4.5.6, 1.2.3.4.5.7
        digests = sha256, sha384, sha512
        ess_cert_id_chain = no
        ess_cert_id_alg = sha256

        执行:wq!保存该文件。

      2. 执行如下命令创建根证书。

        openssl genrsa -out tsca_pri.pem 3072

        openssl req -new -config x509_tsca.cnf -out tsca.csr -key tsca_pri.pem

        openssl x509 -req -in tsca.csr -CA rootcaG1.pem -CAkey rootca_priG1_pri.pem -CAcreateserial -out tsca.pem -days 3650 -extensions extensions -extfile x509_tsca.cnf

        openssl x509 -in tsca.pem -inform pem -outform der -out tsca.der

    • 生成签名证书。
      1. 执行vi x509_signcert.cnf命令生成并编写x509_signcert.cnf文件,将如下内容加入到该文件中。
        [ req ]
        default_bits = 2048
        distinguished_name = req_distinguished_name
        prompt = no
        string_mask = utf8only
        x509_extensions = extensions
        
        [ req_distinguished_name ]
        C = CN
        O = Test
        CN = Signing Certificate G1
        #emailAddress = cmscbb@huawei.com
        
        [ extensions ]
        subjectKeyIdentifier = hash
        authorityKeyIdentifier = keyid, issuer
        basicConstraints = CA:FALSE
        keyUsage = critical, nonRepudiation, digitalSignature
        extendedKeyUsage = codeSigning

        执行:wq!保存该文件。

      2. 执行如下命令创建根证书。

        openssl genrsa -out signcert_pri.pem 3072

        openssl req -new -config x509_signcert.cnf -out signcert.csr -key signcert_pri.pem

        openssl x509 -req -in signcert.csr -CA signca.pem -CAkey signca_pri.pem -CAcreateserial -out signcert.pem -days 3650 -extensions extensions -extfile x509_signcert.cnf

        openssl x509 -in signcert.pem -inform pem -outform der -out signcert.der

    • 生成时间戳证书。
      1. 执行vi x509_tsa.cnf命令生成并编写x509_tsa.cnf文件,将如下内容加入到该文件中。
        [ req ]
        default_bits = 2048
        distinguished_name = req_distinguished_name
        prompt = no
        string_mask = utf8only
        x509_extensions = extensions
        
        [ req_distinguished_name ]
        C = CN
        O = Test
        CN = Timestamp Certificate G1
        #emailAddress = cmscbb@huawei.com
        
        [ extensions ]
        subjectKeyIdentifier = hash
        authorityKeyIdentifier = keyid, issuer
        basicConstraints = critical, CA:FALSE
        keyUsage = critical, nonRepudiation, digitalSignature
        extendedKeyUsage = critical, timeStamping
        
        [ tsa ]
        default_tsa = tsa_config1
        
        [ tsa_config1 ]
        serial = ./serial
        crypto_device = builtin
        #certs = ./certs/tsa.pem
        signer_digest = sha256
        default_policy	= 1.2.3.4.1
        other_policies	= 1.2.3.4.5.6, 1.2.3.4.5.7
        digests = sha256, sha384, sha512
        ess_cert_id_chain = no
        ess_cert_id_alg = sha256

        执行:wq!保存该文件。

      2. 执行如下命令创建根证书。

        openssl genrsa -out ts_pri.pem 3072

        openssl req -new -config x509_tsa.cnf -out ts.csr -key ts_pri.pem

        openssl x509 -req -in ts.csr -CA tsca.pem -CAkey tsca_pri.pem -CAcreateserial -out ts.pem -days 3650 -extensions extensions -extfile x509_tsa.cnf

        openssl x509 -in ts.pem -inform pem -outform der -out ts.der

    • 生成CRL文件。
      1. 执行vi x509_crl.cnf命令生成并编写x509_crl.cnf文件,将如下内容加入到该文件中。
        [ ca ]
        default_ca=CA_default
        
        [ CA_default ]
        database=./index
        crlnumber=./crlnumber
        private_key=./rootca_priG1_pri.pem
        crl_extensions=crl_ext
        default_days=365
        default_crl_days=30
        default_md=default
        preserve=no
        
        [ crl_ext ]
        authorityKeyIdentifier=keyid
      2. 执行vi signcrl.cnf命令生成并编写signcrl.cnf文件,将如下内容加入到该文件中。
        [ ca ]
        default_ca=CA_default
        
        [ CA_default ]
        database=./index
        crlnumber=./crlnumbersign
        private_key=./signca_pri.pem
        crl_extensions=crl_ext
        default_days=365
        default_crl_days=30
        default_md=default
        preserve=no
        
        [ crl_ext ]
        authorityKeyIdentifier=keyid
      3. 执行vi tscrl.cnf命令生成并编写tscrl.cnf文件,将如下内容加入到该文件中。
        [ ca ]
        default_ca=CA_default
        
        [ CA_default ]
        database=./index
        crlnumber=./crlnumberts
        private_key=./tsca_pri.pem
        crl_extensions=crl_ext
        default_days=365
        default_crl_days=30
        default_md=default
        preserve=no
        
        [ crl_ext ]
        authorityKeyIdentifier=keyid
      4. 执行如下命令生成crl文件。

        touch index

        echo unique_subject=no > index.attr

        echo 01 > crlnumber

        echo 05 > crlnumbersign

        echo 09 > crlnumberts

        openssl ca -gencrl -key rootca_priG1_pri.pem -cert rootcaG1.pem -out crl.pem -config x509_crl.cnf

        openssl crl -in crl.pem -inform pem -outform der -out rootG1.crl

        openssl ca -gencrl -key signca_pri.pem -cert signca.pem -out signcrl.pem -config signcrl.cnf

        openssl crl -in signcrl.pem -inform pem -outform der -out sign.crl

        openssl ca -gencrl -key tsca_pri.pem -cert tsca.pem -out tscrl.pem -config tscrl.cnf

        openssl crl -in tscrl.pem -inform pem -outform der -out ts.crl

  3. 用户的根证书rootcaG1.der需要使用华为根证书进行CMS签名。

    1. 进行签名前,需要执行如下命令对用户根证书进行预处理。

      python3.7 /usr/local/software/driver/source/vendor/hisi/tools/signtool/image_pack/esbc_header.py -raw_img ./rootcaG1.der -out_img ./user.der -version 1.1.1.1.1 -nvcnt 0 -tag usrcert -platform hi1951

      digest=`sha256sum user.der | awk '{print $1}'`

      echo "usrcert, ${digest};" > ./usrcert.ini

    2. 将上述语句生成的usrcert.ini发送至华为工程师获取签名文件。用户获取到usrcert.ini.cmsusrcert.ini.crl文件后,执行如下命令生成user.xer文件:

      python3.7 /usr/local/software/driver/source/vendor/hisi/tools/signtool/image_pack/image_pack.py -raw_img ./user.der -out_img ./user.xer -cms ./usrcert.ini.cms -ini ./usrcert.ini -crl ./usrcert.ini.crl --addcms -version 1.1.1.1.1 -platform hi1951

    3. 执行如下命令生成证书吊销列表文件user.crl。

      cat rootG1.crl sign.crl ts.crl signca.der tsca.der > user.crl

    经过以上操作获取到用户根证书文件user.xer和证书吊销列表文件user.crl

  4. 步骤1-2完成CMS签名依赖的各类证书创建,现将5生成的initrd.ini文件拷贝到当前目录下。
  5. 载入Python虚拟环境,使用cmssign工具生成CMS签名文件。

    执行如下命令,对initrd.ini文件进行CMS签名,合成带时间戳的CMS签名文件。

    cmssign sign --signer signcert.pem --key signcert_pri.pem --tssigner ts.pem --tskey ts_pri.pem --in initrd.ini --out initrd.ini.cms

  6. 执行如下命令,合成crl文件。

    cat rootG1.crl sign.crl ts.crl signca.der tsca.der > initrd.ini.crl

    执行完以上步骤生成initrd.ini.cms和initrd.ini.crl文件,完成CMS签名