请求证书并查看已颁发的证书

本主题介绍了如何向 Certificate Authority Service 请求证书以及如何查看已颁发的证书。

准备工作

确保您拥有 CA Service Certificate Requester (roles/privateca.certificateRequester) 或 CA Service Certificate Manager (roles/privateca.certificateManager) IAM 角色。如需详细了解 CA Service 的预定义 IAM 角色,请参阅使用 IAM 进行访问权限控制

如需了解如何向主账号授予 IAM 角色,请参阅授予单个角色

概览

您可以使用以下方法请求证书:

  1. 生成您自己的私钥或公钥,然后提交证书签名请求 (CSR)。
  2. 让 CA Service 为您创建私钥或公钥。
  3. 使用现有的 Cloud Key Management Service (Cloud KMS) 密钥。

使用 CSR 请求证书

必须先生成 CSR,然后才能继续。生成 CSR 后,请执行以下操作:

控制台

  1. 前往 Google Cloud 控制台中的 Certificate Authority Service 页面。

    转到 Certificate Authority Service

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

  3. 点击要从中签发证书的 CA 的名称。

  4. 在“CA 详细信息”页面底部,点击请求证书

  5. 可选:如果您要使用证书模板,请点击 ,从列表中选择一个模板,然后点击保存

  6. 点击提供 CSR

  7. 可选:如需覆盖自动生成的证书名称,请在证书名称字段中输入自定义名称。

  8. 可选:如需为证书选择自定义有效期,请在有效期字段中输入值。

  9. 将您的 CSR 复制并粘贴到 Certificate CSR 框中。如需上传 CSR,请点击浏览

  10. 点击下一步

下载已签署的证书

  1. 如需复制证书,请点击 。 如需以 .crt 文件的形式下载证书,请点击 下载证书
  2. 可选:如需下载证书链,请点击下载证书链
  3. 点击完成

gcloud

gcloud privateca certificates create CERT_ID \
     --issuer-pool POOL_ID \
     --csr CSR_FILENAME \
     --cert-output-file CERT_FILENAME \
     --validity "P30D"

替换以下内容:

  • CERT_ID:证书的唯一标识符。
  • POOL_ID:CA 池的名称。
  • CSR_FILENAME:用于存储 PEM 编码的 CSR 的文件。

--validity 标志定义了证书的有效期。这是一个可选标志,默认值为 30 天。

如需详细了解 gcloud privateca certificates create 命令,请参阅 gcloud privateca Certificate create

Terraform

resource "google_privateca_certificate_authority" "test_ca" {
  pool                     = "my-pool"
  certificate_authority_id = "my-certificate-authority"
  location                 = "us-central1"
  deletion_protection      = false # set to true to prevent destruction of the resource
  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" "default" {
  pool                  = "my-pool"
  location              = "us-central1"
  certificate_authority = google_privateca_certificate_authority.test_ca.certificate_authority_id
  lifetime              = "860s"
  name                  = "my-certificate"
  pem_csr               = tls_cert_request.example.cert_request_pem
}

resource "tls_private_key" "example" {
  algorithm = "RSA"
}

resource "tls_cert_request" "example" {
  private_key_pem = tls_private_key.example.private_key_pem

  subject {
    common_name  = "example.com"
    organization = "ACME Examples, Inc"
  }
}

REST API

  1. 使用您的首选方法(例如 openssl)生成证书签名请求 (CSR)。

    以下是针对 JSON 编码的 CSR 示例。

    -----BEGIN CERTIFICATE REQUEST-----\nMIIChTCCAW0CAQAwQDELMAkGA1UEBhMCVVMxCzAJBgNVBAgMAkNBMQ8wDQYDVQQK\nDAZKb29uaXgxEzARBgNVBAMMCmpvb25peC5uZXQwggEiMA0GCSqGSIb3DQEBAQUA\nA4IBDwAwggEKAoIBAQCnyy+5vcRQUBPqAse3ojmWjyUvhcJK6eLRXpp0teEUF5kg\nHb2ov8gYXb9sSim5fnvs09dGYDKibSrL4Siy7lA/NzMzWtKwyQQeLIQq/cLUJVcd\ndItJ0VRcqr+UPkTCii2vrdcocNDChHM1J8chDdl6DkpYieSTqZwlPcWlQBGAINmT\nT3Q0ZarIVM5l74j13WPuToGrhbVOIZXWxWqJjlHbBA8B/VKtSRCzM1qG60y8Pu2f\n6c78Dfg8+CGRzGwnz8aFS0Yf9czT9luNHSadS/RHjvE9FPZCsinz+6mJlXRcphi1\nKaHsDbstUAhse1h5E9Biyr9SFYRHxY7qRv9aSJ/dAgMBAAGgADANBgkqhkiG9w0B\nAQsFAAOCAQEAZz+I9ff1Rf3lTewXRUpA7nr5HVO1ojCR93Pf27tI/hvNH7z7GwnS\noScoJlClxeRqABOCnfmVoRChullb/KmER4BZ/lF0GQpEtbqbjgjkEDpVlBKCb0+L\nHE9psplIz6H9nfFS3Ouoiodk902vrMEh0LyDYNQuqFoyCZuuepUlK3NmtmkexlgT\n0pJg/5FV0iaQ+GiFXSZhTC3drfiM/wDnXGiqpbW9WmebSij5O+3BNYXKBUgqmT3r\nbryFydNq4qSOIbnN/MNb4UoKno3ve7mnGk9lIDf9UMPvhl+bT7C3OLQLGadJroME\npYnKLoZUvRwEdtZpbNL9QhCAm2QiJ6w+6g==\n-----END CERTIFICATE REQUEST-----
    
  2. 请求证书。

    HTTP 方法和网址:

    POST https://privateca.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/caPools/POOL_ID/certificates?certificate_id=CERTIFICATE_ID

    请求 JSON 正文:

    {
     "lifetime": {
       "seconds": 3600,
       "nanos": 0
     },
     "pem_csr": "PEM_CSR"
    }
    

    如需发送您的请求,请展开以下选项之一:

    您应该收到类似以下内容的 JSON 响应:

    {
     "name": "projects/project-id/locations/location/certificateAuthorities/ca-id/certificates/certificate-id",
     "pemCertificate": "-----BEGIN CERTIFICATE-----...",
     "certificateDescription": {...}
    }
    

使用自动生成的密钥请求证书

控制台

您可以使用 Google Cloud 控制台生成客户端或服务器 TLS 证书。

  1. 在 Google Cloud 控制台中,前往 Certificate Authority Service 页面。

    转到 Certificate Authority Service

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

  3. 点击要从中签发证书的 CA 的名称。

  4. 证书授权机构详细信息页面底部,点击请求证书

  5. 可选:如果您要使用证书模板,请点击 ,从列表中选择一个模板,然后点击保存

  6. 点击输入详细信息

  7. 可选:将自动生成的证书名称替换为唯一的自定义名称。

  8. 可选:如需为证书选择自定义有效期,请在有效期字段中输入值。

添加域名

  1. 添加域名下的域名 1 字段中输入域名。
  2. 可选:如果要添加多个域名,请点击添加项,然后在域名 2 字段中输入另一个域名。

扩展的密钥用途

  1. 可选:在扩展密钥用法下,根据您的用例从以下选项中进行选择:

    • 服务器 TLS:这些证书可让您对服务器的身份进行身份验证。
    • 客户端 TLS:这些证书可让您对请求者的身份进行身份验证。
  2. 点击下一步

配置密钥大小和算法

  1. 可选:在配置密钥大小和算法下,从列表中选择签名密钥大小和算法。如果您跳过此步骤,则会使用具有 SHA 256 摘要的 RSASSA-PSS 2048 位密钥。如需了解如何选择签名密钥和算法,请参阅选择密钥算法
  2. 点击继续

下载已签署的证书

  1. 可选:如需下载 PEM 编码的证书链,请点击下载证书链
  2. 可选:如需下载关联的 PEM 编码私钥,请点击下载私钥

  3. 点击完成

gcloud

如需使用自动生成的密钥功能,您需要安装 Python 加密密钥 (PyCA) 库。如需了解如何安装 Pyca 加密库,请参阅添加 Pyca 加密库

如需创建证书,请使用以下 gcloud 命令:

gcloud privateca certificates create \
  --issuer-pool POOL_ID \
  --generate-key \
  --key-output-file KEY_FILENAME \
  --cert-output-file CERT_FILENAME \
  --dns-san "DNS_NAME" \
  --use-preset-profile "CERTIFICATE_PROFILE"

替换以下内容:

  • POOL_ID:CA 池的名称。
  • KEY_FILENAME:必须写入生成的私钥文件的路径。
  • CERT_FILENAME:必须写入 PEM 编码的证书链文件的路径。证书链按从最终实体到根的顺序进行排序。
  • DNS_NAME:一个或多个以英文逗号分隔的 DNS 主题备用名称 (SAN)。
  • CERTIFICATE_PROFILE证书配置文件的唯一标识符。例如,为终端实体服务器 TLS 使用 leaf_server_tls

gcloud 命令会提及以下标志:

  • --generate-key:在您的计算机上生成新的 RSA-2048 私钥。

您也可以使用以下标志的任意组合:

  • --dns-san:允许您传递一个或多个以英文逗号分隔的 DNS SAN。
  • --ip-san:允许您传递一个或多个以英文逗号分隔的 IP SAN。
  • --uri-san:允许您传递一个或多个以英文逗号分隔的 URI SAN。
  • --subject:允许您传递证书主题的 X.501 名称。

如需详细了解 gcloud privateca certificates create 命令,请参阅 gcloud privateca Certificate create

Go

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

import (
	"context"
	"fmt"
	"io"

	privateca "cloud.google.com/go/security/privateca/apiv1"
	"cloud.google.com/go/security/privateca/apiv1/privatecapb"
	"google.golang.org/protobuf/types/known/durationpb"
)

// Create a Certificate which is issued by the Certificate Authority present in the CA Pool.
// The key used to sign the certificate is created by the Cloud KMS.
func createCertificate(
	w io.Writer,
	projectId string,
	location string,
	caPoolId string,
	caId string,
	certId string,
	commonName string,
	domainName string,
	certDuration int64,
	publicKeyBytes []byte) error {
	// projectId := "your_project_id"
	// location := "us-central1"		// For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
	// caPoolId := "ca-pool-id"			// The CA Pool id in which the certificate authority exists.
	// caId := "ca-id"					// The name of the certificate authority which issues the certificate.
	// certId := "certificate"			// A unique name for the certificate.
	// commonName := "cert-name"		// A common name for the certificate.
	// domainName := "cert.example.com"	// Fully qualified domain name for the certificate.
	// certDuration := int64(31536000)	// The validity of the certificate in seconds.
	// publicKeyBytes 					// The public key used in signing the certificates.

	ctx := context.Background()
	caClient, err := privateca.NewCertificateAuthorityClient(ctx)
	if err != nil {
		return fmt.Errorf("NewCertificateAuthorityClient creation failed: %w", err)
	}
	defer caClient.Close()

	// Set the Public Key and its format.
	publicKey := &privatecapb.PublicKey{
		Key:    publicKeyBytes,
		Format: privatecapb.PublicKey_PEM,
	}

	// Set Certificate subject config.
	subjectConfig := &privatecapb.CertificateConfig_SubjectConfig{
		Subject: &privatecapb.Subject{
			CommonName: commonName,
		},
		SubjectAltName: &privatecapb.SubjectAltNames{
			DnsNames: []string{domainName},
		},
	}

	// Set the X.509 fields required for the certificate.
	x509Parameters := &privatecapb.X509Parameters{
		KeyUsage: &privatecapb.KeyUsage{
			BaseKeyUsage: &privatecapb.KeyUsage_KeyUsageOptions{
				DigitalSignature: true,
				KeyEncipherment:  true,
			},
			ExtendedKeyUsage: &privatecapb.KeyUsage_ExtendedKeyUsageOptions{
				ServerAuth: true,
				ClientAuth: true,
			},
		},
	}

	// Set certificate settings.
	cert := &privatecapb.Certificate{
		CertificateConfig: &privatecapb.Certificate_Config{
			Config: &privatecapb.CertificateConfig{
				PublicKey:     publicKey,
				SubjectConfig: subjectConfig,
				X509Config:    x509Parameters,
			},
		},
		Lifetime: &durationpb.Duration{
			Seconds: certDuration,
		},
	}

	fullCaPoolName := fmt.Sprintf("projects/%s/locations/%s/caPools/%s", projectId, location, caPoolId)

	// Create the CreateCertificateRequest.
	// See https://pkg.go.dev/cloud.google.com/go/security/privateca/apiv1/privatecapb#CreateCertificateRequest.
	req := &privatecapb.CreateCertificateRequest{
		Parent:                        fullCaPoolName,
		CertificateId:                 certId,
		Certificate:                   cert,
		IssuingCertificateAuthorityId: caId,
	}

	_, err = caClient.CreateCertificate(ctx, req)
	if err != nil {
		return fmt.Errorf("CreateCertificate failed: %w", err)
	}

	fmt.Fprintf(w, "Certificate %s created", certId)

	return nil
}

Java

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


import com.google.api.core.ApiFuture;
import com.google.cloud.security.privateca.v1.CaPoolName;
import com.google.cloud.security.privateca.v1.Certificate;
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.CreateCertificateRequest;
import com.google.cloud.security.privateca.v1.KeyUsage;
import com.google.cloud.security.privateca.v1.KeyUsage.ExtendedKeyUsageOptions;
import com.google.cloud.security.privateca.v1.KeyUsage.KeyUsageOptions;
import com.google.cloud.security.privateca.v1.PublicKey;
import com.google.cloud.security.privateca.v1.PublicKey.KeyFormat;
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.protobuf.ByteString;
import com.google.protobuf.Duration;
import java.io.IOException;
import java.util.concurrent.ExecutionException;

public class CreateCertificate {

  public static void main(String[] args)
      throws InterruptedException, ExecutionException, IOException {
    // TODO(developer): Replace these variables before running the sample.

    // publicKeyBytes: Public key used in signing the certificates.
    // location: For a list of locations, see:
    // https://cloud.google.com/certificate-authority-service/docs/locations
    // poolId: Set a unique id for the CA pool.
    // certificateAuthorityName: The name of the certificate authority which issues the certificate.
    // certificateName: Set a unique name for the certificate.
    String project = "your-project-id";
    ByteString publicKeyBytes = ByteString.copyFrom(new byte[]{});
    String location = "ca-location";
    String poolId = "ca-poolId";
    String certificateAuthorityName = "certificate-authority-name";
    String certificateName = "certificate-name";

    createCertificate(
        project, location, poolId, certificateAuthorityName, certificateName, publicKeyBytes);
  }

  // Create a Certificate which is issued by the Certificate Authority present in the CA Pool.
  // The public key used to sign the certificate can be generated using any crypto
  // library/framework.
  public static void createCertificate(
      String project,
      String location,
      String poolId,
      String certificateAuthorityName,
      String certificateName,
      ByteString publicKeyBytes)
      throws InterruptedException, ExecutionException, IOException {
    // 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()) {

      // commonName: Enter a title for your certificate.
      // orgName: Provide the name of your company.
      // domainName: List the fully qualified domain name.
      // certificateLifetime: The validity of the certificate in seconds.
      String commonName = "commonname";
      String orgName = "orgname";
      String domainName = "dns.example.com";
      long certificateLifetime = 1000L;

      // Set the Public Key and its format.
      PublicKey publicKey =
          PublicKey.newBuilder().setKey(publicKeyBytes).setFormat(KeyFormat.PEM).build();

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

      // Set the X.509 fields required for the certificate.
      X509Parameters x509Parameters =
          X509Parameters.newBuilder()
              .setKeyUsage(
                  KeyUsage.newBuilder()
                      .setBaseKeyUsage(
                          KeyUsageOptions.newBuilder()
                              .setDigitalSignature(true)
                              .setKeyEncipherment(true)
                              .setCertSign(true)
                              .build())
                      .setExtendedKeyUsage(
                          ExtendedKeyUsageOptions.newBuilder().setServerAuth(true).build())
                      .build())
              .setCaOptions(CaOptions.newBuilder().setIsCa(true).buildPartial())
              .build();

      // Create certificate.
      Certificate certificate =
          Certificate.newBuilder()
              .setConfig(
                  CertificateConfig.newBuilder()
                      .setPublicKey(publicKey)
                      .setSubjectConfig(subjectConfig)
                      .setX509Config(x509Parameters)
                      .build())
              .setLifetime(Duration.newBuilder().setSeconds(certificateLifetime).build())
              .build();

      // Create the Certificate Request.
      CreateCertificateRequest certificateRequest =
          CreateCertificateRequest.newBuilder()
              .setParent(CaPoolName.of(project, location, poolId).toString())
              .setCertificateId(certificateName)
              .setCertificate(certificate)
              .setIssuingCertificateAuthorityId(certificateAuthorityName)
              .build();

      // Get the Certificate response.
      ApiFuture<Certificate> future =
          certificateAuthorityServiceClient
              .createCertificateCallable()
              .futureCall(certificateRequest);

      Certificate response = future.get();
      // Get the PEM encoded, signed X.509 certificate.
      System.out.println(response.getPemCertificate());
      // To verify the obtained certificate, use this intermediate chain list.
      System.out.println(response.getPemCertificateChainList());
    }
  }
}

Python

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

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

def create_certificate(
    project_id: str,
    location: str,
    ca_pool_name: str,
    ca_name: str,
    certificate_name: str,
    common_name: str,
    domain_name: str,
    certificate_lifetime: int,
    public_key_bytes: bytes,
) -> None:
    """
    Create a Certificate which is issued by the Certificate Authority present in the CA Pool.
    The key used to sign the certificate is created by the Cloud KMS.

    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 a unique name for the CA pool.
        ca_name: the name of the certificate authority which issues the certificate.
        certificate_name: set a unique name for the certificate.
        common_name: a title for your certificate.
        domain_name: fully qualified domain name for your certificate.
        certificate_lifetime: the validity of the certificate in seconds.
        public_key_bytes: public key used in signing the certificates.
    """

    caServiceClient = privateca_v1.CertificateAuthorityServiceClient()

    # The public key used to sign the certificate can be generated using any crypto library/framework.
    # Also you can use Cloud KMS to retrieve an already created public key.
    # For more info, see: https://cloud.google.com/kms/docs/retrieve-public-key.

    # Set the Public Key and its format.
    public_key = privateca_v1.PublicKey(
        key=public_key_bytes,
        format_=privateca_v1.PublicKey.KeyFormat.PEM,
    )

    subject_config = privateca_v1.CertificateConfig.SubjectConfig(
        subject=privateca_v1.Subject(common_name=common_name),
        subject_alt_name=privateca_v1.SubjectAltNames(dns_names=[domain_name]),
    )

    # Set the X.509 fields required for the certificate.
    x509_parameters = privateca_v1.X509Parameters(
        key_usage=privateca_v1.KeyUsage(
            base_key_usage=privateca_v1.KeyUsage.KeyUsageOptions(
                digital_signature=True,
                key_encipherment=True,
            ),
            extended_key_usage=privateca_v1.KeyUsage.ExtendedKeyUsageOptions(
                server_auth=True,
                client_auth=True,
            ),
        ),
    )

    # Create certificate.
    certificate = privateca_v1.Certificate(
        config=privateca_v1.CertificateConfig(
            public_key=public_key,
            subject_config=subject_config,
            x509_config=x509_parameters,
        ),
        lifetime=duration_pb2.Duration(seconds=certificate_lifetime),
    )

    # Create the Certificate Request.
    request = privateca_v1.CreateCertificateRequest(
        parent=caServiceClient.ca_pool_path(project_id, location, ca_pool_name),
        certificate_id=certificate_name,
        certificate=certificate,
        issuing_certificate_authority_id=ca_name,
    )
    result = caServiceClient.create_certificate(request=request)

    print("Certificate creation result:", result)

使用现有 Cloud KMS 密钥请求证书

如需使用 Cloud KMS 密钥创建终端实体服务器 TLS 证书,请运行以下命令:

gcloud privateca certificates create \
  --issuer-pool POOL_ID \
  --kms-key-version projects/PROJECT_ID/locations/LOCATION_ID/keyRings/KEY_RING/cryptoKeys/KEY/cryptoKeyVersions/KEY_VERSION \
  --cert-output-file CERT_FILENAME \
  --dns-san "DNS_NAME" \
  --use-preset-profile "leaf_server_tls"

替换以下内容:

  • POOL_ID:CA 池的名称。
  • PROJECT_ID:项目 ID。
  • LOCATION_ID:密钥环的位置。
  • KEY_RING:密钥所在密钥环的名称。
  • KEY:键的名称。
  • KEY_VERSION:密钥的版本。
  • CERT_FILENAME:PEM 编码的证书链文件的路径。证书链文件按从最终实体到根的顺序进行排序。
  • DNS_NAME:以英文逗号分隔的 DNS SAN。

使用证书执行常见操作

本部分介绍如何使用证书执行某些常见操作。

从 CA 池中的特定 CA 颁发证书

gcloud

如需以 CA 池中的特定 CA 颁发证书,请添加 --ca 标志和必须颁发证书的 CA 的 CA_ID

gcloud privateca certificates create \
  --issuer-pool POOL_ID \
  --ca CA_ID \
  --generate-key \
  --key-output-file KEY_FILENAME \
  --cert-output-file CERT_FILENAME \
  --dns-san "DNS_NAME" \
  --use-preset-profile "leaf_server_tls"

控制台

Google Cloud 控制台仅支持从特定 CA 颁发证书。按照使用自动生成的密钥请求证书部分或使用 CSR 请求证书部分中的说明,选择必须颁发证书的 CA。

Terraform

resource "google_privateca_certificate_authority" "authority" {
  // 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-sample-certificate-authority"
  location                 = "us-central1"
  deletion_protection      = false # set to true to prevent destruction of the resource
  config {
    subject_config {
      subject {
        organization = "HashiCorp"
        common_name  = "my-certificate-authority"
      }
      subject_alt_name {
        dns_names = ["hashicorp.com"]
      }
    }
    x509_config {
      ca_options {
        is_ca = true
      }
      key_usage {
        base_key_usage {
          digital_signature = true
          cert_sign         = true
          crl_sign          = true
        }
        extended_key_usage {
          server_auth = true
        }
      }
    }
  }
  lifetime = "86400s"
  key_spec {
    algorithm = "RSA_PKCS1_4096_SHA256"
  }
}

resource "google_privateca_certificate" "default" {
  pool     = "my-pool"
  location = "us-central1"
  lifetime = "860s"
  name     = "my-sample-certificate"
  config {
    subject_config {
      subject {
        common_name         = "san1.example.com"
        country_code        = "us"
        organization        = "google"
        organizational_unit = "enterprise"
        locality            = "mountain view"
        province            = "california"
        street_address      = "1600 amphitheatre parkway"
        postal_code         = "94109"
      }
    }
    x509_config {
      ca_options {
        is_ca = false
      }
      key_usage {
        base_key_usage {
          crl_sign = true
        }
        extended_key_usage {
          server_auth = true
        }
      }
    }
    public_key {
      format = "PEM"
      key    = base64encode(data.tls_public_key.example.public_key_pem)
    }
  }
  // Certificates require an authority to exist in the pool, though they don't
  // need to be explicitly connected to it
  depends_on = [google_privateca_certificate_authority.authority]
}

resource "tls_private_key" "example" {
  algorithm = "RSA"
}

data "tls_public_key" "example" {
  private_key_pem = tls_private_key.example.private_key_pem
}

查看已颁发的证书

控制台

  1. 在 Google Cloud 控制台中,前往 Certificate Authority Service 页面。

    转到 Certificate Authority Service

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

  3. 证书授权机构页面上,点击 CA 的名称。

  4. 证书授权机构详细信息页面底部,点击查看已颁发的证书以查看 CA 颁发的证书列表。

    您可以在所有证书页面上查看这些证书。详细信息包括证书的状态、颁发证书的 CA、包含该 CA 的 CA 池、证书的失效日期等。

gcloud

如需列出 CA 池中由特定 CA 颁发的所有证书,请使用以下 gcloud 命令:

gcloud privateca certificates list --issuer-pool ISSUER_POOL --ca CA_NAME

如需详细了解 gcloud privateca certificates list 命令,请参阅 gcloud privateca Certificate list

如需列出给定位置中所有 CA 的所有证书,请使用以下 gcloud 命令:

gcloud privateca certificates list --location LOCATION

Go

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

import (
	"context"
	"fmt"
	"io"

	privateca "cloud.google.com/go/security/privateca/apiv1"
	"cloud.google.com/go/security/privateca/apiv1/privatecapb"
	"google.golang.org/api/iterator"
)

// List Certificates present in the given CA pool.
func listCertificates(
	w io.Writer,
	projectId string,
	location string,
	caPoolId string) error {
	// projectId := "your_project_id"
	// location := "us-central1"		// For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
	// caPoolId := "ca-pool-id"			// The CA Pool id in which the certificate exists.

	ctx := context.Background()
	caClient, err := privateca.NewCertificateAuthorityClient(ctx)
	if err != nil {
		return fmt.Errorf("NewCertificateAuthorityClient creation failed: %w", err)
	}
	defer caClient.Close()

	fullCaName := fmt.Sprintf("projects/%s/locations/%s/caPools/%s", projectId, location, caPoolId)

	// Create the ListCertificatesRequest.
	// See https://pkg.go.dev/cloud.google.com/go/security/privateca/apiv1/privatecapb#ListCertificatesRequest.
	req := &privatecapb.ListCertificatesRequest{Parent: fullCaName}

	it := caClient.ListCertificates(ctx, req)
	for {
		resp, err := it.Next()
		if err == iterator.Done {
			break
		}
		if err != nil {
			return fmt.Errorf("unable to get the list of cerficates: %w", err)
		}

		fmt.Fprintf(w, " - %s (common name: %s)", resp.Name,
			resp.CertificateDescription.SubjectDescription.Subject.CommonName)
	}

	return nil
}

Java

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


import com.google.cloud.security.privateca.v1.CaPoolName;
import com.google.cloud.security.privateca.v1.Certificate;
import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient;
import java.io.IOException;

public class ListCertificates {

  public static void main(String[] args) throws 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: Id of the CA pool which contains the certificates to be listed.
    String project = "your-project-id";
    String location = "ca-location";
    String poolId = "ca-pool-id";
    listCertificates(project, location, poolId);
  }

  // List Certificates present in the given CA pool.
  public static void listCertificates(String project, String location, String poolId)
      throws IOException {
    // 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()) {

      CaPoolName caPool =
          CaPoolName.newBuilder()
              .setProject(project)
              .setLocation(location)
              .setCaPool(poolId)
              .build();

      // Retrieve and print the certificate names.
      System.out.println("Available certificates: ");
      for (Certificate certificate :
          certificateAuthorityServiceClient.listCertificates(caPool).iterateAll()) {
        System.out.println(certificate.getName());
      }
    }
  }
}

Python

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


import google.cloud.security.privateca_v1 as privateca_v1

def list_certificates(
    project_id: str,
    location: str,
    ca_pool_name: str,
) -> None:
    """
    List Certificates present 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: name of the CA pool which contains the certificates to be listed.
    """

    caServiceClient = privateca_v1.CertificateAuthorityServiceClient()

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

    # Retrieve and print the certificate names.
    print(f"Available certificates in CA pool {ca_pool_name}:")
    for certificate in caServiceClient.list_certificates(parent=ca_pool_path):
        print(certificate.name)

查看单个证书的详细信息

控制台

  1. 在 Google Cloud 控制台中,前往 Certificate Authority Service 页面。

    转到 Certificate Authority Service

  2. CA 管理器标签页下选择您的目标 CA。

  3. 点击 CA 名称。

  4. 证书授权机构详细信息页面底部,点击查看已颁发的证书以查看已颁发证书的列表。

  5. 在要下载的证书的操作列中,点击

  6. 下载下,点击证书。您可以点击证书链下载证书链

gcloud

如需查看证书的完整说明,请运行以下命令:

gcloud privateca certificates describe CERT_NAME \
    --issuer-pool POOL_ID

如需详细了解 gcloud privateca certificates describe 命令,请参阅 gcloud privateca Certificate describe

如需将 PEM 编码的 X.509 证书链导出到文件,请运行以下命令:

gcloud privateca certificates export CERT_NAME \
    --issuer-pool POOL_ID \
    --include-chain \
    --output-file certificate-file

如需详细了解 gcloud privateca certificates export 命令,请参阅 gcloud privateca 证书导出

证书的持有证明

私钥的持有证明可确保证书请求者持有该证书的私钥。仅当请求者根据 RFC 2986 提供 PKCS #10 CSR 时,CA Service 才会检查所有权证明。但系统不会强制执行其他形式的证书请求(例如 CertificateConfig 发出的请求)的持有证明。

接受证书的客户端应用会负责验证证书持有者是否拥有该证书的私钥。在证书颁发期间强制执行所有权证明检查,是一种深度防御机制,旨在防范行为不当的客户端。无论 CA 是否检查所有权证明,此类客户端的存在都可能构成安全漏洞。

后续步骤