建立從屬憑證授權單位

本頁說明如何在 CA 集區中建立從屬憑證授權單位 (CA)。

下層 CA 負責直接向使用者、電腦和裝置等終端實體核發憑證。從屬 CA 會由父項 CA (通常是根 CA) 進行加密簽署。因此,信任根 CA 的系統會自動信任從屬 CA,以及從屬 CA 核發的終端實體憑證。

事前準備

  • 確認您具備 CA 服務作業管理員 (roles/privateca.caManager) 或 CA 服務管理員 (roles/privateca.admin) IAM 角色。詳情請參閱「設定 IAM 政策」。
  • 建立 CA 集區
  • 選取根 CA。

建立從屬 CA

與根 CA 相比,從屬 CA 更容易撤銷及輪替。如果您有多個憑證核發情境,可以為每個情境建立從屬 CA。在 CA 集區中新增多個從屬 CA,有助於更妥善地平衡分配憑證要求,並提高總有效 QPS

如要建立下層 CA,請按照下列步驟操作:

控制台

  1. 前往Google Cloud 控制台的「Certificate Authority Service」(憑證授權單位服務) 頁面。

    前往憑證授權單位服務

  2. 按一下「CA 管理員」分頁標籤。

  3. 按一下「建立 CA」

    使用 Cloud 控制台建立 CA。

選取 CA 類型

  1. 按一下「從屬 CA」
  2. 按一下「根 CA 位於 Google Cloud」
  3. 在「Valid for」(有效期限) 欄位中,輸入您希望 CA 憑證的有效期限。
  4. 選用:選擇 CA 的層級。預設層級為「Enterprise」(企業)。詳情請參閱「選取作業層級」。
  5. 按一下「區域」,為 CA 選取位置。詳情請參閱「位置」一節。
  6. 選用步驟:在「Initialized state」(初始化狀態) 下方,選取憑證授權單位在建立時必須處於的狀態。
  7. 選用:在「設定核發情境」下方,按一下「憑證設定檔」,然後從清單中選取最符合需求的憑證設定檔。詳情請參閱「憑證設定檔」。
  8. 點選「下一步」
設定 CA 主體名稱
  1. 在「Organization (O)」(機構 (O)) 欄位中,輸入貴公司名稱。
  2. 選用:在「機構單位 (OU)」欄位中,輸入公司部門或業務單位。
  3. 選用:在「Country name (C)」(國家/地區名稱 (C)) 欄位中,輸入兩個英文字母的國家/地區代碼。
  4. 選用:在「州/省名稱」欄位中,輸入您所在州/省的名稱。
  5. 選用:在「Locality name」(所在地名稱) 欄位中輸入城市名稱。
  6. 在「CA common name (CN)」(CA 一般名稱 (CN)) 欄位中,輸入 CA 名稱。
  7. 按一下「繼續」
設定 CA 金鑰大小和演算法
  1. 請選擇最符合需求的金鑰演算法。如要瞭解如何決定合適的金鑰演算法,請參閱「選擇金鑰演算法」。
  2. 按一下「繼續」
設定 CA 構件
  1. 選擇要使用 Google 代管或客戶代管的 Cloud Storage 值區。
    1. 如果是 Google 管理的 Cloud Storage 值區,CA 服務會在與 CA 相同的位置建立 Google 管理的值區。
    2. 如果是客戶代管的 Cloud Storage 值區,請按一下「瀏覽」,然後選取現有的 Cloud Storage 值區。
  2. 按一下「繼續」
新增標籤

下列步驟為選用步驟。

如要為 CA 新增標籤,請按照下列步驟操作:

  1. 按一下「新增項目」
  2. 在「Key 1」欄位中,輸入標籤鍵。
  3. 在「Value 1」(值 1) 欄位中輸入標籤值。
  4. 如要新增其他標籤,請按一下「新增項目」。然後,按照步驟 2 和 3 所述,新增標籤鍵和值。
  5. 按一下「繼續」
檢查設定

詳閱所有設定,然後按一下「完成」建立 CA。

gcloud

  1. 為從屬 CA 建立 CA 集區:

    gcloud privateca pools create SUBORDINATE_POOL_ID --location=LOCATION
    

    更改下列內容:

    • SUBORDINATE_POOL_ID:CA 集區的名稱。
    • LOCATION:要建立 CA 集區的位置。如需完整清單,請參閱「地點」。

    如要進一步瞭解如何建立 CA 集區,請參閱「建立 CA 集區」。

    如要進一步瞭解 gcloud privateca pools create 指令,請參閱 gcloud privateca pools create

  2. 在建立的 CA 集區中建立從屬 CA。

    gcloud privateca subordinates create SUBORDINATE_CA_ID \
        --pool=SUBORDINATE_POOL_ID \
        --location=LOCATION \
        --issuer-pool=POOL_ID \
        --issuer-location=ISSUER_LOCATION \
        --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 服務或他處的下層 CA。

Terraform

resource "google_privateca_certificate_authority" "root_ca" {
  // 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-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 = "ACME"
        common_name  = "my-certificate-authority"
      }
    }
    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 {
        }
      }
    }
  }
  key_spec {
    algorithm = "RSA_PKCS1_4096_SHA256"
  }
  // valid for 10 years
  lifetime = "${10 * 365 * 24 * 3600}s"
}

resource "google_privateca_certificate_authority" "sub_ca" {
  // This example assumes this pool already exists.
  // Pools cannot be deleted in normal test circumstances, so we depend on static pools
  pool                     = "my-sub-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 = "ACME"
        common_name  = "my-subordinate-authority"
      }
    }
    x509_config {
      ca_options {
        is_ca = true
        # Force the sub CA to only issue leaf certs.
        # Use e.g.
        #    max_issuer_path_length = 1
        # if you need to chain more subordinates.
        zero_max_issuer_path_length = true
      }
      key_usage {
        base_key_usage {
          cert_sign = true
          crl_sign  = true
        }
        extended_key_usage {
        }
      }
    }
  }
  // valid for 5 years
  lifetime = "${5 * 365 * 24 * 3600}s"
  key_spec {
    algorithm = "RSA_PKCS1_2048_SHA256"
  }
  type = "SUBORDINATE"
}

Java

如要向 CA 服務進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。


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 服務進行驗證,請設定應用程式預設憑證。 詳情請參閱「為本機開發環境設定驗證」。

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」(憑證授權單位服務) 頁面。

    前往憑證授權單位服務

  2. 按一下「CA 管理員」分頁標籤。

  3. 在「憑證授權單位」下方,選取要啟用的 CA。

  4. 按一下「啟用」

  5. 在隨即開啟的對話方塊中,按一下「下載 CSR」,即可下載核發憑證的 CA 可簽署的 PEM 編碼 CSR 檔案。

  6. 點選「下一步」

  7. 在「Upload Certificate Chain」(上傳憑證鏈) 欄位中,按一下「Browse」(瀏覽)

  8. 上傳副檔名為 .crt 的簽署憑證檔案。

  9. 按一下「Activate」。

gcloud

如要啟用新建立的下層 CA,請執行下列指令:

gcloud privateca subordinates enable SUBORDINATE_CA_ID \
--pool=SUBORDINATE_POOL_ID \
--location=LOCATION

更改下列內容:

  • SUBORDINATE_CA_ID:下層 CA 的專屬 ID。
  • SUBORDINATE_POOL_ID:包含從屬 CA 的 CA 集區名稱。
  • LOCATION:CA 集區的位置。如需完整的位置清單,請參閱「位置」。

如要進一步瞭解 gcloud privateca subordinates enable 指令,請參閱 gcloud privateca subordinates enable

Terraform

在從屬 CA 上將欄位 desired_state 設為 ENABLED,然後執行 terraform apply

後續步驟