国密SSL证书的正确配置核心在于严格区分证书用途,这主要通过  `Key  Usage`  和  `Extended  Key  Usage`  两个扩展属性来定义。目前国密证书主要有两种应用模式:遵循  `GM/T  0015`  标准的单证书模式,以及  `TLCP`  协议下专用的双证书模式。

一、Key  Usage(密钥用法)

`Key  Usage`  定义了证书公钥最基础的密码学功能,是用途的第一道关口。

关键性:根据RFC  5280标准,此扩展应设为  critical  (关键),强制应用程序严格遵守其限制。

OID  (对象标识符):`2.5.29.15`。

各用途位(Bit)及GM/T  0015标准建议用法如下表所示:

用途位  (Usage  Bit)      建议使用场景  

`digitalSignature`      用于签名证书、SSL/TLS  客户端证书。  

`nonRepudiation`  (contentCommitment)      与  `digitalSignature`  类似,用于法律上不可否认的签名证书,如电子合同签署。  

`keyEncipherment`      用于SSL/TLS  服务器证书的密钥交换,或加密证书的公钥加密。  

  `dataEncipherment`      用于加密证书,直接对数据进行加密。  

  `keyAgreement`      用于执行密钥协商的证书,如部分SM2加密证书。  

  `keyCertSign`          仅用于CA证书,表示可用于签发其他证书。  

  `cRLSign`          仅用于CA证书,表示可用于签发CRL证书撤销列表。  

*注意:CA证书也应标记  `keyCertSign`  和  `cRLSign`。*

二、Extended  Key  Usage(扩展密钥用法/EKU)

`Extended  Key  Usage`  在Key  Usage之上进一步细化证书的高级应用场景。

关键性:由签发者选择是否标记为  `critical`。

OID  (对象标识符):`2.5.29.37`。

EKU常见用途OID及其应用场景如下:

EKU  目的  (Purpose)    OID      建议使用场景  

  `serverAuth`      `1.3.6.1.5.5.7.3.1`      用于TLS/SSL服务器身份验证(网站、服务端)。  

  `clientAuth`      `1.3.6.1.5.5.7.3.2`      用于TLS/SSL客户端身份验证(用户、设备)。  

  `codeSigning`      `1.3.6.1.5.5.7.3.3`      用于对代码或软件进行数字签名。  

`emailProtection`      `1.3.6.1.5.5.7.3.4`      用于保护电子邮件安全(如S/MIME)。  

  `timeStamping`      `1.3.6.1.5.5.7.3.8`      用于时间戳服务。  

  `OCSPSigning`      `1.3.6.1.5.5.7.3.9`      用于OCSP响应器签名。  

三、场景配置指南

国密证书有两种常见形式:'单证书'和'双证书'。它们的配置思路详见下表:

证书类型      Key  Usage  (关键)      Extended  Key  Usage  (非关键)      说明  

签名证书          `digitalSignature`,  `nonRepudiation`      `clientAuth`,  `codeSigning`,  `emailProtection`      签名用途广泛,应避免用于加密。  

加密证书          `keyEncipherment`,  `dataEncipherment`,  `keyAgreement`      通常不设置          仅限于密钥传输、加密等操作,不能签名。  

SSL  服务器证书(双证书场景)          签名证书用  `digitalSignature`,加密证书用  `keyEncipherment`      签名证书通常包含  `serverAuth`  和  `clientAuth`;加密证书不设置          仅签名证书用于身份验证和协商。  

SSL  服务器证书(单证书场景)          `digitalSignature`,  `keyEncipherment`      `serverAuth`      同时支持签名和加密,但功能未分离。  

SSL  客户端证书(用于双向TLS)          `digitalSignature`      `clientAuth`  |  核心是用于客户端身份认证。  

代码签名证书          `digitalSignature`      `codeSigning`      确保软件开发者和代码来源可信。  

CA  证书(证书颁发机构)          `keyCertSign`,  `cRLSign`          不设置**  (CA证书不含此扩展)      仅用于签发下级证书和CRL。  

四、配置示例

在签发证书时,可以通过配置文件的方式进行设置。

在  `openssl.cnf`  (或  `gmssl.cnf`)  文件中配置:

```ini

[  v3_ca_extensions  ]    #  CA证书的扩展配置

basicConstraints  =  critical,  CA:true

keyUsage  =  critical,  keyCertSign,  cRLSign

subjectKeyIdentifier  =  hash

authorityKeyIdentifier  =  keyid:always,  issuer

[  v3_server_extensions  ]    #  SSL服务器证书的扩展配置  (单证书模式)

basicConstraints  =  CA:FALSE

keyUsage  =  critical,  digitalSignature,  keyEncipherment

extendedKeyUsage  =  serverAuth

subjectKeyIdentifier  =  hash

authorityKeyIdentifier  =  keyid:always,  issuer

[  v3_client_extensions  ]    #  SSL客户端证书的扩展配置

basicConstraints  =  CA:FALSE

keyUsage  =  critical,  digitalSignature

extendedKeyUsage  =  clientAuth

subjectKeyIdentifier  =  hash

authorityKeyIdentifier  =  keyid:always,  issuer

[  v3_code_signing_extensions  ]    #  代码签名证书的扩展配置

basicConstraints  =  CA:FALSE

keyUsage  =  critical,  digitalSignature

extendedKeyUsage  =  codeSigning

subjectKeyIdentifier  =  hash

authorityKeyIdentifier  =  keyid:always,  issuer

```

签发证书操作命令:

```bash

  生成受信任的CA证书:

openssl  req  -x509  -newkey  ec  -pkeyopt  ec_paramgen_curve:sm2p256v1  \

    -keyout  CAKey.pem  -out  CACert.pem  -days  3650  -nodes  \

    -config  openssl.cnf  -extensions  v3_ca_extensions

  生成并签发服务器证书:

openssl  req  -new  -newkey  ec  -pkeyopt  ec_paramgen_curve:sm2p256v1  \

    -keyout  ServerKey.pem  -out  ServerReq.pem  -nodes

openssl  x509  -req  -in  ServerReq.pem  -CA  CACert.pem  -CAkey  CAKey.pem  \

    -out  ServerCert.pem  -days  365  -CAcreateserial  -extfile  openssl.cnf  \

    -extensions  v3_server_extensions

```

五、常见问题与排坑指南

1.    为什么我的国密算法运行失败?  程序报错最常见的原因是该用于签名的SSL证书  `KeyUsage`  中未包含  `digitalSignature`,或应加密的证书未包含  `keyEncipherment`。解决方案:务必先检查证书扩展属性。

2.    什么是国密双证书?  国密SSL协议(GM/T  0024)标准采用“签名证书”与“加密证书”分离的双证书机制,服务器和用户各自持有两对独立密钥对,加密和签名字段必须严格区分。

3.    如何快速检查证书的用途设置?  使用支持国密的OpenSSL或GmSSL工具即可以查看:

        ```bash

        gmssl  x509  -in  sm2_cert.pem  -text  -noout  |  grep  -A  5  -B  1  "Key  Usage"

        ```

4.    为什么我的服务器SSL证书在国密浏览器中显示不安全?  很可能签发时将用于签名和用于加密的证书用反了。

5.    一个证书能否既是客户端又是服务器端?技术上可行,但强烈不推荐。将二者混合到一个证书中违背了最小权限原则,会增加安全风险,审计上也不合规,建议分别为服务器和客户端角色签发专用证书。

6.    EKU与KeyUsage冲突了会怎样?  两者的定义不能冲突。例如,若KeyUsage只允许数字签名,EKU却要求密钥加密,互不兼容的应用会拒绝使用该证书。