删除证书授权机构

借助 Certificate Authority Service,您可以删除现有的证书授权机构 (CA)。CA 将在从发起删除流程之日起 30 天的宽限期后永久删除。宽限期结束后,CA 服务会永久删除 CA 及其所有嵌套工件,例如证书和证书吊销列表 (CRL)。

已删除的 CA 使用的任何客户管理的 Google Cloud 资源(例如 Cloud Storage 存储分区或 Cloud Key Management Service 密钥)都不会被删除。如需详细了解 Google 管理的资源和客户管理的资源,请参阅管理资源

在宽限期内,我们不会对已删除的 CA 收费。不过,如果您恢复 CA,则系统会按 CA 在 DELETED 状态下存在的时间,按照 CA 的结算层级向您收费。

准备工作

  • 确保您拥有 CA Service Operation Manager (roles/privateca.caManager) 或 CA Service Admin (roles/privateca.admin) Identity and Access Management (IAM) 角色。如需详细了解 CA 服务的预定义 IAM 角色,请参阅使用 IAM 进行访问权限控制

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

  • 确保 CA 满足以下条件:

    • CA 必须处于 AWAITING_USER_ACTIVATIONDISABLEDSTAGED 状态。如需了解详情,请参阅证书授权机构状态
    • CA 不得包含有效证书。证书满足以下条件时,即被视为处于有效状态:

      • 证书的“自”和“至”日期有效。
      • 证书尚未被撤消。
      • 使用证书的设备或系统信任颁发证书的证书授权机构 (CA)。

    在删除 CA 之前,请确保已撤消该 CA 颁发的所有有效证书。您无法撤消已删除的 CA 颁发的证书。

删除 CA

如需发起 CA 删除流程,请执行以下操作:

控制台

  1. 前往 Google Cloud 控制台中的证书颁发机构页面。

    前往“证书授权机构”页面

  2. 在 CA 列表中,选择要删除的 CA。
  3. 点击 删除。系统随即会显示删除证书授权机构对话框。
  4. 可选:如果您符合以下条件,请选中以下一个或两个复选框:
    • 删除此 CA(即使存在有效证书)

      通过此选项,您可以删除包含有效证书的 CA。删除包含有效证书的 CA 可能会导致依赖于这些证书的网站、应用或系统失败。我们建议您先撤消 CA 颁发的所有有效证书,然后再删除 CA。

    • 跳过 30 天的宽限期,立即删除此 CA

      30 天的宽限期可让您撤消此 CA 颁发的所有证书,并验证没有任何系统依赖于此 CA。我们建议在非生产环境或测试环境中使用此选项,以防止可能的中断和数据丢失。

  5. 点击确认

gcloud

  1. 检查 CA 状态,确保其已停用。您只能删除处于 DISABLED 状态的 CA。

    gcloud privateca roots describe CA_ID --pool=POOL_ID \
      --format="value(state)"
    

    替换以下内容:

    • CA_ID:CA 的唯一标识符。
    • POOL_ID:包含 CA 的 CA 池的名称。

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

  2. 如果 CA 未停用,请运行以下命令停用 CA。

    gcloud privateca roots disable CA_ID --pool=POOL_ID
    

    如需详细了解 gcloud privateca roots disable 命令,请参阅 gcloud privateca roots disable

  3. 删除 CA。

    gcloud privateca roots delete CA_ID --pool=POOL_ID
    

    您可以在 gcloud 命令中添加 --ignore-active-certificates 标志,即使 CA 具有有效证书,也可以删除该 CA。

    如需详细了解 gcloud privateca roots delete 命令,请参阅 gcloud privateca roots delete

  4. 出现提示时,确认您要删除 CA。

    确认后,系统会安排删除 CA,并开始 30 天的宽限期。该命令会输出 CA 的预计删除日期和时间。

    Deleted Root CA [projects/PROJECT_ID/locations/us-west1/caPools/POOL_ID/certificateAuthorities/CA_ID] can be undeleted until 2020-08-14T19:28:39Z.
    

Go

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

import (
	"context"
	"fmt"
	"io"

	privateca "cloud.google.com/go/security/privateca/apiv1"
	"cloud.google.com/go/security/privateca/apiv1/privatecapb"
)

// Delete a Certificate Authority from the specified CA pool.
// Before deletion, the CA must be disabled or staged and must not contain any active certificates.
func deleteCa(w io.Writer, projectId string, location string, caPoolId string, caId 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 id of the CA pool under which the CA is present.
	// caId := "ca-id"				// The id of the CA to be deleted.

	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/certificateAuthorities/%s",
		projectId, location, caPoolId, caId)

	// Check if the CA is disabled or staged.
	// See https://pkg.go.dev/cloud.google.com/go/security/privateca/apiv1/privatecapb#GetCertificateAuthorityRequest.
	caReq := &privatecapb.GetCertificateAuthorityRequest{Name: fullCaName}
	caResp, err := caClient.GetCertificateAuthority(ctx, caReq)
	if err != nil {
		return fmt.Errorf("GetCertificateAuthority failed: %w", err)
	}

	if caResp.State != privatecapb.CertificateAuthority_DISABLED &&
		caResp.State != privatecapb.CertificateAuthority_STAGED {
		return fmt.Errorf("you can only delete disabled or staged Certificate Authorities. %s is not disabled", caId)
	}

	// Create the DeleteCertificateAuthorityRequest.
	// Setting the IgnoreActiveCertificates to True will delete the CA
	// even if it contains active certificates. Care should be taken to re-anchor
	// the certificates to new CA before deleting.
	// See https://pkg.go.dev/cloud.google.com/go/security/privateca/apiv1/privatecapb#DeleteCertificateAuthorityRequest.
	req := &privatecapb.DeleteCertificateAuthorityRequest{
		Name:                     fullCaName,
		IgnoreActiveCertificates: false,
	}

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

	if caResp, err = op.Wait(ctx); err != nil {
		return fmt.Errorf("DeleteCertificateAuthority failed during wait: %w", err)
	}

	if caResp.State != privatecapb.CertificateAuthority_DELETED {
		return fmt.Errorf("unable to delete Certificate Authority. Current state: %s", caResp.State.String())
	}

	fmt.Fprintf(w, "Successfully deleted Certificate Authority: %s.", caId)
	return nil
}

Java

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


import com.google.api.core.ApiFuture;
import com.google.cloud.security.privateca.v1.CertificateAuthority.State;
import com.google.cloud.security.privateca.v1.CertificateAuthorityName;
import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient;
import com.google.cloud.security.privateca.v1.DeleteCertificateAuthorityRequest;
import com.google.longrunning.Operation;
import java.io.IOException;
import java.util.concurrent.ExecutionException;

public class DeleteCertificateAuthority {

  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: The id of the CA pool under which the CA is present.
    // certificateAuthorityName: The name of the CA to be deleted.
    String project = "your-project-id";
    String location = "ca-location";
    String poolId = "ca-pool-id";
    String certificateAuthorityName = "certificate-authority-name";
    deleteCertificateAuthority(project, location, poolId, certificateAuthorityName);
  }

  // Delete the Certificate Authority from the specified CA pool.
  // Before deletion, the CA must be disabled and must not contain any active certificates.
  public static void deleteCertificateAuthority(
      String project, String location, String poolId, String certificateAuthorityName)
      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()) {
      // Create the Certificate Authority Name.
      CertificateAuthorityName certificateAuthorityNameParent =
          CertificateAuthorityName.newBuilder()
              .setProject(project)
              .setLocation(location)
              .setCaPool(poolId)
              .setCertificateAuthority(certificateAuthorityName)
              .build();

      // Check if the CA is enabled.
      State caState =
          certificateAuthorityServiceClient
              .getCertificateAuthority(certificateAuthorityNameParent)
              .getState();
      if (caState == State.ENABLED) {
        System.out.println(
            "Please disable the Certificate Authority before deletion ! Current state: " + caState);
        return;
      }

      // Create the DeleteCertificateAuthorityRequest.
      // Setting the setIgnoreActiveCertificates() to true, will delete the CA
      // even if it contains active certificates. Care should be taken to re-anchor
      // the certificates to new CA before deleting.
      DeleteCertificateAuthorityRequest deleteCertificateAuthorityRequest =
          DeleteCertificateAuthorityRequest.newBuilder()
              .setName(certificateAuthorityNameParent.toString())
              .setIgnoreActiveCertificates(false)
              .build();

      // Delete the Certificate Authority.
      ApiFuture<Operation> futureCall =
          certificateAuthorityServiceClient
              .deleteCertificateAuthorityCallable()
              .futureCall(deleteCertificateAuthorityRequest);
      Operation response = futureCall.get();

      if (response.hasError()) {
        System.out.println("Error while deleting Certificate Authority !" + response.getError());
        return;
      }

      // Check if the CA has been deleted.
      caState =
          certificateAuthorityServiceClient
              .getCertificateAuthority(certificateAuthorityNameParent)
              .getState();
      if (caState == State.DELETED) {
        System.out.println(
            "Successfully deleted Certificate Authority : " + certificateAuthorityName);
      } else {
        System.out.println(
            "Unable to delete Certificate Authority. Please try again ! Current state: " + caState);
      }
    }
  }
}

Python

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

import google.cloud.security.privateca_v1 as privateca_v1


def delete_certificate_authority(
    project_id: str, location: str, ca_pool_name: str, ca_name: str
) -> None:
    """
    Delete the Certificate Authority from the specified CA pool.
    Before deletion, the CA must be disabled and must not contain any active certificates.

    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: the name of the CA pool under which the CA is present.
        ca_name: the name of the CA to be deleted.
    """

    caServiceClient = privateca_v1.CertificateAuthorityServiceClient()
    ca_path = caServiceClient.certificate_authority_path(
        project_id, location, ca_pool_name, ca_name
    )

    # Check if the CA is enabled.
    ca_state = caServiceClient.get_certificate_authority(name=ca_path).state
    if ca_state != privateca_v1.CertificateAuthority.State.DISABLED:
        print(
            "Please disable the Certificate Authority before deletion ! Current state:",
            ca_state,
        )
        raise RuntimeError(
            f"You can only delete disabled Certificate Authorities. "
            f"{ca_name} is not disabled!"
        )

    # Create the DeleteCertificateAuthorityRequest.
    # Setting the ignore_active_certificates to True will delete the CA
    # even if it contains active certificates. Care should be taken to re-anchor
    # the certificates to new CA before deleting.
    request = privateca_v1.DeleteCertificateAuthorityRequest(
        name=ca_path, ignore_active_certificates=False
    )

    # Delete the Certificate Authority.
    operation = caServiceClient.delete_certificate_authority(request=request)
    result = operation.result()

    print("Operation result", result)

    # Get the current CA state.
    ca_state = caServiceClient.get_certificate_authority(name=ca_path).state

    # Check if the CA has been deleted.
    if ca_state == privateca_v1.CertificateAuthority.State.DELETED:
        print("Successfully deleted Certificate Authority:", ca_name)
    else:
        print(
            "Unable to delete Certificate Authority. Please try again ! Current state:",
            ca_state,
        )

查看已删除的 CA 的失效日期

如需查看 CA 何时会被永久删除,请执行以下操作:

控制台

  1. 点击 CA 池管理器标签页。
  2. 点击包含您删除的 CA 的 CA 池的名称。

您可以在 CA 池页面上的表格中查看 CA 的失效日期。

查看已删除的 CA 的到期日期。

gcloud

如需查看 CA 的预期删除时间,请运行以下命令:

gcloud privateca roots describe CA_ID \
  --pool=POOL_ID \
  --format="value(expireTime.date())"

替换以下内容:

  • CA_ID:CA 的名称。
  • POOL_ID:包含 CA 的 CA 池的名称。

该命令会返回 CA 服务删除 CA 的预期日期和时间。

2020-08-14T19:28:39

如需验证 CA 是否已永久删除,请运行以下命令:

gcloud privateca roots describe CA_ID --pool=POOL_ID

如果成功删除 CA,该命令会返回以下错误。

ERROR: (gcloud.privateca.roots.describe) NOT_FOUND: Resource 'projects/PROJECT_ID/locations/LOCATION/caPools/POOL_ID/certificateAuthorities/CA_ID' was not found

后续步骤