跳转至

企业内部证书管理

在企业内部,尤其是开发和测试环境中,我们经常需要为内部服务启用HTTPS。如果每次都购买商业CA签发的证书,成本高且流程繁琐。因此,自建一个内部的证书颁发机构(CA)是一个非常高效和经济的解决方案。

内部CA签发的证书在功能上与商业证书完全一样,唯一的区别是它默认不被操作系统和浏览器信任。但我们只需要在所有需要访问这些内部服务的客户端(员工电脑、服务器等)上,将我们自建的CA根证书安装为“受信任的根证书颁发机构”,就可以实现无缝的HTTPS访问,浏览器也不会再弹出安全警告。

下面是使用 OpenSSL 工具创建内部CA并签发服务器证书的完整流程。


准备工作

确保你的系统上已经安装了 OpenSSL。在Windows上,你可以通过 Git for Windows 自带的 Git Bash 来使用 openssl 命令。


点击这里下载下面步骤做好的图形界面工具。


步骤一:创建CA私钥

CA的私钥是整个信任链的核心,必须妥善保管,绝不能泄露。

# 生成一个4096位的RSA私钥
openssl genpkey -algorithm RSA -out MyInternalCA.key -pkeyopt rsa_keygen_bits:4096
  • genpkey: 用于生成私钥。
  • -algorithm RSA: 指定使用RSA算法。
  • -out MyInternalCA.key: 将生成的私钥保存到 MyInternalCA.key 文件中。
  • -pkeyopt rsa_keygen_bits:4096: 设置密钥长度为4096位,提供了很高的安全性。

步骤二:创建CA根证书(自签名)

利用刚刚生成的私钥,我们来创建一个自签名的根证书。这个证书就是我们的“CA”。

openssl req -x509 -new -nodes -key MyInternalCA.key -sha256 -days 3650 -out MyInternalCA.crt -subj "/C=CN/ST=Shanghai/L=Shanghai/O=My Corp/OU=IT Dept/CN=My Corp Internal CA"
  • req: 用于处理证书请求和生成证书。
  • -x509: 表示我们要输出一个自签名的X.509证书,而不是一个证书请求。
  • -new: 创建一个新的证书。
  • -nodes: 表示“no DES”,即不对私钥进行加密。在生产环境中,你可能需要去掉这个选项,并为私钥设置一个强密码。
  • -key MyInternalCA.key: 指定用于签发证书的私钥。
  • -sha256: 使用SHA-256作为哈希算法。
  • -days 3650: 设置证书的有效期为10年。
  • -out MyInternalCA.crt: 将生成的根证书保存到 MyInternalCA.crt 文件中。
  • -subj: 用于提供证书的主题信息,避免交互式输入。
    • C: Country (国家)
    • ST: State or Province (省份)
    • L: Locality (城市)
    • O: Organization (组织名)
    • OU: Organizational Unit (部门名)
    • CN: Common Name (通用名),对于CA证书,这通常是CA的名称。

现在,你已经有了两个核心文件:MyInternalCA.key (CA私钥) 和 MyInternalCA.crt (CA根证书)。

请将 MyInternalCA.crt 分发给所有需要信任此CA的客户端进行安装。

对于大量客户端电脑,可以通过组策略(GPO)或配置管理工具(如 SCCM、Ansible等)自动分发和安装证书。

步骤三:为你的服务器创建证书

现在,我们扮演CA的角色,为我们的一个内部Web服务(例如 byhy.com)签发一个服务器证书。

1. 为服务器生成一个新的私钥

openssl genpkey -algorithm RSA -out byhy.com.key -pkeyopt rsa_keygen_bits:2048

2. 创建证书签名请求 (CSR - Certificate Signing Request)

CSR文件包含了服务器的公钥和相关信息,我们将用它来向CA申请签名。

openssl req -new -key byhy.com.key -out byhy.com.csr -subj "/C=CN/ST=Shanghai/L=Shanghai/O=My Corp/OU=WebApp/CN=byhy.com" -addext "subjectAltName = DNS:byhy.com, DNS:*.byhy.com"
  • 注意 CN (Common Name): 这里必须填写你的服务的完整域名,浏览器将通过它来验证证书是否匹配。

  • 注意 subjectAltName: 这里可以添加其他的域名,让证书适用于多个域名,例如 *.byhy.net。 目前的浏览器必须需要这个字段,即使你没有其他的域名,也一定要添加这个。 否则会出现 net::ERR_CERT_COMMON_NAME_INVALID 错误。

3. 使用你的CA签发服务器证书

这是最关键的一步。我们用CA的私钥和根证书,来对服务器的CSR文件进行签名,从而生成最终的服务器证书。

openssl x509 -req -in byhy.com.csr -CA MyInternalCA.crt -CAkey MyInternalCA.key -CAcreateserial -out byhy.com.crt -days 365 -sha256 -copy_extensions copyall
  • -req: 表示输入的是一个CSR文件。
  • -in byhy.com.csr: 指定输入的CSR文件。
  • -CA MyInternalCA.crt: 指定用于签名的CA根证书。
  • -CAkey MyInternalCA.key: 指定用于签名的CA私钥。
  • -CAcreateserial: 创建一个序列号文件(例如 MyInternalCA.srl),CA用它来追踪签发过的证书,这是必需的。
  • -out byhy.com.crt: 生成的最终服务器证书。
  • -days 365: 签发的证书有效期为1年。
  • -sha256: 使用SHA-256作为哈希算法。
  • -copy_extensions copyall: 将CSR文件中的扩展复制到最终的证书中,例如 subjectAltNamekeyUsage 等。

步骤四:使用证书

在Nginx中

如果你使用Nginx作为反向代理,你可以使用 proxy_ssl_certificateproxy_ssl_certificate_key 参数来配置Nginx来使用你的证书。

    server {
        listen       443 ssl;
        server_name  byhy.com *.byhy.com;

        ssl_certificate      byhy.com.crt;
        ssl_certificate_key  byhy.com.key;

        ssl_session_cache    shared:SSL:1m;
        ssl_session_timeout  5m;

        ssl_ciphers  HIGH:!aNULL:!MD5;
        ssl_prefer_server_ciphers  on;


        root         .\z_dist; 
        access_log   off;   

        location / {
          try_files $uri $uri/index.html;
        }

        location /api/ {
            proxy_pass         http://auth;
            proxy_redirect     off;
            proxy_set_header   Host $host;
            proxy_http_version 1.1;
            add_header Access-Control-Allow-Origin *;
        }
    }

在ASP.NET Core中

为了在Kestrel服务器中使用我们新生成的HTTPS证书,通常需要将服务器证书和其私钥合并到一个 .pfx 文件中。

openssl pkcs12 -export -out byhy.com.pfx -inkey byhy.com.key -in byhy.com.crt
执行此命令时,会提示你为 .pfx 文件设置一个导出密码,请务必记住它。

然后,你可以在 appsettings.json 中配置Kestrel来使用这个证书:

{
  "Kestrel": {
    "Endpoints": {
      "Https": {
        "Url": "https://localhost:5001",
        "Certificate": {
          "Path": "path/to/your/byhy.com.pfx",
          "Password": "your-pfx-password"
        }
      }
    }
  }
}

总结

通过以上步骤,你就拥有了一个完整的企业内部PKI(公钥基础设施)雏形。你可以用这个CA为任意多的内部服务签发证书,从而实现内部网络全面的HTTPS加密,大大提升安全性。