创建从属证书授权机构

本页面介绍如何在 CA 池中创建从属证书授权机构 (CA)。

从属 CA 负责直接向最终实体(例如用户、计算机和设备)颁发证书。从属 CA 由父 CA(通常是根 CA)进行加密签名。因此,信任根 CA 的系统将自动信任从属 CA 和从属 CA 颁发的最终实体证书。

准备工作

  • 确保您拥有 CA Service Operation Manager (roles/privateca.caManager) 或 CA Service Admin (roles/privateca.admin) IAM 角色。如需了解详情,请参阅配置 IAM 政策
  • 创建 CA 池
  • 选择您的根 CA。

创建从属 CA

与根 CA 相比,从属 CA 更容易撤消和轮替。如果您有多个证书颁发场景,则可以为每种场景创建从属 CA。在 CA 池中添加多个从属 CA 有助于您更好地对证书请求进行负载均衡和提高总有效 QPS

如需创建从属 CA,请执行以下操作:

控制台

  1. 转到 Google Cloud 控制台中的 Certificate Authority Service 页面。

    转到 Certificate Authority Service

  2. 点击 CA 管理员标签页。

  3. 点击创建 CA

    使用 Cloud 控制台创建 CA。

选择 CA 类型

  1. 点击从属 CA
  2. 点击根 CA 位于 Google Cloud 中
  3. 有效期字段中,输入希望 CA 证书的有效期。
  4. 可选:为 CA 选择层级。默认层级为企业。如需了解详情,请参阅选择操作层级
  5. 点击区域,为 CA 选择一个位置。如需了解详情,请参阅位置
  6. 可选:在初始化状态下,选择 CA 在创建时必须处于的状态。
  7. 可选:在设置颁发场景下,点击证书配置文件,然后从列表中选择最符合您的要求的证书配置文件。如需了解详情,请参阅证书配置文件
  8. 点击下一步
配置 CA 主题名称
  1. 组织 (O) 字段中,输入贵公司的名称。
  2. 可选:在组织部门 (OU) 字段中,输入公司下级或业务部门。
  3. 可选:在国家/地区名称字段中,输入由两个字母组成的国家/地区代码。
  4. 可选:在州或省/自治区/直辖市名称字段中,输入您所在州的名称。
  5. 可选:在 Locality name(市行政区名称)字段中,输入您所在城市的名称。
  6. CA 通用名称 (CN) 字段中,输入 CA 名称。
  7. 池 ID 字段中,输入 CA 池名称。创建 CA 后便无法更改 CA 池。
  8. 点击下一步
配置 CA 密钥大小和算法
  1. 选择最符合您需求的密钥算法。如需了解如何确定合适的密钥算法,请参阅选择密钥算法
  2. 点击下一步
配置 CA 工件

以下步骤是可选的。如果您跳过这些步骤,系统将应用默认设置。

  1. 选择是使用 Google 管理的 Cloud Storage 存储桶还是自行管理的 Cloud Storage 存储桶。
  2. 如果您未选择自行管理的 Cloud Storage 存储桶,CA Service 会在与 CA 相同的位置创建一个 Google 管理的存储桶。

  3. 选择是否禁止向 Cloud Storage 存储桶发布证书吊销列表 (CRL) 和 CA 证书。
  4. 默认情况下,系统会在 Cloud Storage 存储桶上发布 CRL 和 CA 证书。如需停用这些设置,请点击切换开关。

  5. 点击下一步
添加标签

以下步骤是可选步骤。

如果要为 CA 添加标签,请执行以下操作:

  1. 点击 添加一项
  2. 键 1 字段中,输入标签键。
  3. 值 1 字段中,输入标签值。
  4. 如果您要添加其他标签,请点击 添加一项。然后,添加第 2 步和第 3 步中所述的标签键和值。
  5. 点击下一步
查看设置

仔细检查所有设置,然后点击创建以创建 CA。

gcloud

  1. 为从属 CA 创建 CA 池:

    gcloud privateca pools create SUBORDINATE_POOL_ID
    

    SUBORDINATE_POOL_ID 替换为 CA 池的名称。

    如需详细了解如何创建 CA 池,请参阅创建 CA 池

    如需详细了解 gcloud privateca pools create 命令,请参阅 gcloud privatecapool create

  2. 在创建的 CA 池中创建从属 CA。

    gcloud privateca subordinates create SUBORDINATE_CA_ID \
      --pool=SUBORDINATE_POOL_ID \
      --issuer-pool=POOL_ID \
      --key-algorithm="ec-p256-sha256" \
      --subject="CN=Example Server TLS CA, O=Example LLC"
    

    创建从属 CA 时,系统会返回以下语句。

    Created Certificate Authority [projects/my-project-pki/locations/us-west1/caPools/SUBORDINATE_POOL_ID/certificateAuthorities/SUBORDINATE_CA_ID].
    

    如需查看完整的设置列表,请运行以下 gcloud 命令:

    gcloud privateca subordinates create --help
    

    该命令会返回一些示例,以创建其颁发者位于 CA Service 或位于其他位置的从属 CA。

Terraform

resource "google_privateca_certificate_authority" "root_ca" {
  pool                                   = "my-pool"
  certificate_authority_id               = "my-certificate-authority-root"
  location                               = "us-central1"
  deletion_protection                    = false # set to true to prevent destruction of the resource
  ignore_active_certificates_on_deletion = true
  config {
    subject_config {
      subject {
        organization = "HashiCorp"
        common_name  = "my-certificate-authority"
      }
      subject_alt_name {
        dns_names = ["hashicorp.com"]
      }
    }
    x509_config {
      ca_options {
        # is_ca *MUST* be true for certificate authorities
        is_ca = true
      }
      key_usage {
        base_key_usage {
          # cert_sign and crl_sign *MUST* be true for certificate authorities
          cert_sign = true
          crl_sign  = true
        }
        extended_key_usage {
          server_auth = false
        }
      }
    }
  }
  key_spec {
    algorithm = "RSA_PKCS1_4096_SHA256"
  }
}

resource "google_privateca_certificate_authority" "default" {
  // This example assumes this pool already exists.
  // Pools cannot be deleted in normal test circumstances, so we depend on static pools
  pool                     = "my-pool"
  certificate_authority_id = "my-certificate-authority-sub"
  location                 = "us-central1"
  deletion_protection      = false # set to true to prevent destruction of the resource
  subordinate_config {
    certificate_authority = google_privateca_certificate_authority.root_ca.name
  }
  config {
    subject_config {
      subject {
        organization = "HashiCorp"
        common_name  = "my-subordinate-authority"
      }
      subject_alt_name {
        dns_names = ["hashicorp.com"]
      }
    }
    x509_config {
      ca_options {
        is_ca = true
        # Force the sub CA to only issue leaf certs
        max_issuer_path_length = 0
      }
      key_usage {
        base_key_usage {
          digital_signature  = true
          content_commitment = true
          key_encipherment   = false
          data_encipherment  = true
          key_agreement      = true
          cert_sign          = true
          crl_sign           = true
          decipher_only      = true
        }
        extended_key_usage {
          server_auth      = true
          client_auth      = false
          email_protection = true
          code_signing     = true
          time_stamping    = true
        }
      }
    }
  }
  lifetime = "86400s"
  key_spec {
    algorithm = "RSA_PKCS1_4096_SHA256"
  }
  type = "SUBORDINATE"
}

Java

如需向 CA Service 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证


import com.google.api.core.ApiFuture;
import com.google.cloud.security.privateca.v1.CaPoolName;
import com.google.cloud.security.privateca.v1.CertificateAuthority;
import com.google.cloud.security.privateca.v1.CertificateAuthority.KeyVersionSpec;
import com.google.cloud.security.privateca.v1.CertificateAuthority.SignHashAlgorithm;
import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient;
import com.google.cloud.security.privateca.v1.CertificateConfig;
import com.google.cloud.security.privateca.v1.CertificateConfig.SubjectConfig;
import com.google.cloud.security.privateca.v1.CreateCertificateAuthorityRequest;
import com.google.cloud.security.privateca.v1.KeyUsage;
import com.google.cloud.security.privateca.v1.KeyUsage.KeyUsageOptions;
import com.google.cloud.security.privateca.v1.Subject;
import com.google.cloud.security.privateca.v1.SubjectAltNames;
import com.google.cloud.security.privateca.v1.X509Parameters;
import com.google.cloud.security.privateca.v1.X509Parameters.CaOptions;
import com.google.longrunning.Operation;
import com.google.protobuf.Duration;
import java.io.IOException;
import java.util.concurrent.ExecutionException;

public class CreateSubordinateCa {

  public static void main(String[] args)
      throws InterruptedException, ExecutionException, IOException {
    // TODO(developer): Replace these variables before running the sample.
    // location: For a list of locations, see:
    // https://cloud.google.com/certificate-authority-service/docs/locations
    // poolId: Set it to the CA Pool under which the CA should be created.
    // subordinateCaName: Unique name for the Subordinate CA.
    String project = "your-project-id";
    String location = "ca-location";
    String poolId = "ca-pool-id";
    String subordinateCaName = "subordinate-certificate-authority-name";

    createSubordinateCertificateAuthority(project, location, poolId, subordinateCaName);
  }

  public static void createSubordinateCertificateAuthority(
      String project, String location, String poolId, String subordinateCaName)
      throws IOException, ExecutionException, InterruptedException {
    // Initialize client that will be used to send requests. This client only needs to be created
    // once, and can be reused for multiple requests. After completing all of your requests, call
    // the `certificateAuthorityServiceClient.close()` method on the client to safely
    // clean up any remaining background resources.
    try (CertificateAuthorityServiceClient certificateAuthorityServiceClient =
        CertificateAuthorityServiceClient.create()) {

      String commonName = "commonname";
      String orgName = "csr-org-name";
      String domainName = "dns.example.com";
      int caDuration = 100000; // Validity of this CA in seconds.

      // Set the type of Algorithm.
      KeyVersionSpec keyVersionSpec =
          KeyVersionSpec.newBuilder().setAlgorithm(SignHashAlgorithm.RSA_PKCS1_4096_SHA256).build();

      // Set CA subject config.
      SubjectConfig subjectConfig =
          SubjectConfig.newBuilder()
              .setSubject(
                  Subject.newBuilder().setCommonName(commonName).setOrganization(orgName).build())
              // Set the fully qualified domain name.
              .setSubjectAltName(SubjectAltNames.newBuilder().addDnsNames(domainName).build())
              .build();

      //  Set the key usage options for X.509 fields.
      X509Parameters x509Parameters =
          X509Parameters.newBuilder()
              .setKeyUsage(
                  KeyUsage.newBuilder()
                      .setBaseKeyUsage(
                          KeyUsageOptions.newBuilder().setCrlSign(true).setCertSign(true).build())
                      .build())
              .setCaOptions(CaOptions.newBuilder().setIsCa(true).build())
              .build();

      // Set certificate authority settings.
      CertificateAuthority subCertificateAuthority =
          CertificateAuthority.newBuilder()
              .setType(CertificateAuthority.Type.SUBORDINATE)
              .setKeySpec(keyVersionSpec)
              .setConfig(
                  CertificateConfig.newBuilder()
                      .setSubjectConfig(subjectConfig)
                      .setX509Config(x509Parameters)
                      .build())
              // Set the CA validity duration.
              .setLifetime(Duration.newBuilder().setSeconds(caDuration).build())
              .build();

      // Create the CertificateAuthorityRequest.
      CreateCertificateAuthorityRequest subCertificateAuthorityRequest =
          CreateCertificateAuthorityRequest.newBuilder()
              .setParent(CaPoolName.of(project, location, poolId).toString())
              .setCertificateAuthorityId(subordinateCaName)
              .setCertificateAuthority(subCertificateAuthority)
              .build();

      // Create Subordinate CA.
      ApiFuture<Operation> futureCall =
          certificateAuthorityServiceClient
              .createCertificateAuthorityCallable()
              .futureCall(subCertificateAuthorityRequest);

      Operation response = futureCall.get();

      if (response.hasError()) {
        System.out.println("Error while creating Subordinate CA !" + response.getError());
        return;
      }

      System.out.println(
          "Subordinate Certificate Authority created successfully : " + subordinateCaName);
    }
  }
}

Python

如需向 CA Service 进行身份验证,请设置应用默认凭据。如需了解详情,请参阅为本地开发环境设置身份验证

import google.cloud.security.privateca_v1 as privateca_v1
from google.protobuf import duration_pb2

def create_subordinate_ca(
    project_id: str,
    location: str,
    ca_pool_name: str,
    subordinate_ca_name: str,
    common_name: str,
    organization: str,
    domain: str,
    ca_duration: int,
) -> None:
    """
    Create Certificate Authority (CA) which is the subordinate CA in the given CA Pool.
    Args:
        project_id: project ID or project number of the Cloud project you want to use.
        location: location you want to use. For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
        ca_pool_name: set it to the CA Pool under which the CA should be created.
        subordinate_ca_name: unique name for the Subordinate CA.
        common_name: a title for your certificate authority.
        organization: the name of your company for your certificate authority.
        domain: the name of your company for your certificate authority.
        ca_duration: the validity of the certificate authority in seconds.
    """

    ca_service_client = privateca_v1.CertificateAuthorityServiceClient()

    # Set the type of Algorithm
    key_version_spec = privateca_v1.CertificateAuthority.KeyVersionSpec(
        algorithm=privateca_v1.CertificateAuthority.SignHashAlgorithm.RSA_PKCS1_4096_SHA256
    )

    # Set CA subject config.
    subject_config = privateca_v1.CertificateConfig.SubjectConfig(
        subject=privateca_v1.Subject(
            common_name=common_name, organization=organization
        ),
        # Set the fully qualified domain name.
        subject_alt_name=privateca_v1.SubjectAltNames(dns_names=[domain]),
    )

    # Set the key usage options for X.509 fields.
    x509_parameters = privateca_v1.X509Parameters(
        key_usage=privateca_v1.KeyUsage(
            base_key_usage=privateca_v1.KeyUsage.KeyUsageOptions(
                crl_sign=True,
                cert_sign=True,
            )
        ),
        ca_options=privateca_v1.X509Parameters.CaOptions(
            is_ca=True,
        ),
    )

    # Set certificate authority settings.
    certificate_authority = privateca_v1.CertificateAuthority(
        type_=privateca_v1.CertificateAuthority.Type.SUBORDINATE,
        key_spec=key_version_spec,
        config=privateca_v1.CertificateConfig(
            subject_config=subject_config,
            x509_config=x509_parameters,
        ),
        # Set the CA validity duration.
        lifetime=duration_pb2.Duration(seconds=ca_duration),
    )

    ca_pool_path = ca_service_client.ca_pool_path(project_id, location, ca_pool_name)

    # Create the CertificateAuthorityRequest.
    request = privateca_v1.CreateCertificateAuthorityRequest(
        parent=ca_pool_path,
        certificate_authority_id=subordinate_ca_name,
        certificate_authority=certificate_authority,
    )

    operation = ca_service_client.create_certificate_authority(request=request)
    result = operation.result()

    print(f"Operation result: {result}")

启用从属 CA

如需启用从属 CA,请执行以下操作:

控制台

  1. 转到 Google Cloud 控制台中的 Certificate Authority Service 页面。

    转到 Certificate Authority Service

  2. 点击 CA 管理员标签页。

  3. 证书授权机构下,选择您要激活的 CA。

  4. 点击 启用

  5. 在打开的对话框中,点击下载 CSR,下载 PEM 编码的 CSR 文件,签发证书的 CA 可以对其进行签名。

  6. 点击下一步

  7. 上传证书链字段中,点击浏览

  8. 上传扩展名为 .crt 的已签名证书文件。

  9. 点击 Activate(激活)。

gcloud

如需启用新创建的从属 CA,请运行以下命令:

gcloud privateca subordinates enable SUBORDINATE_CA_ID --pool=SUBORDINATE_POOL_ID

替换以下内容:

  • SUBORDINATE_CA_ID:从属 CA 的唯一标识符。
  • SUBORDINATE_POOL_ID:包含从属 CA 的 CA 池的名称。

如需详细了解 gcloud privateca subordinates enable 命令,请参阅 gcloud privateca subordinates enable

Terraform

在从属 CA 上将字段 desired_state 设置为 ENABLED,并运行 terraform apply

后续步骤