하위 인증 기관 만들기

이 페이지에서는 CA 풀에서 하위 인증 기관(CA)을 만드는 방법을 설명합니다.

하위 CA는 사용자, 컴퓨터, 기기 등의 종단 개체에 직접 인증서를 발급합니다. 하위 CA는 대개 루트 CA인 상위 CA에 의해 암호화 방식으로 서명됩니다. 따라서 루트 CA를 신뢰하는 시스템은 하위 CA와 하위 CA가 발급하는 종단 개체 인증서를 자동으로 신뢰합니다.

시작하기 전에

  • CA Service 작업 관리자(roles/privateca.caManager) 또는 CA Service 관리자(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 등급을 선택합니다. 기본 등급은 Enterprise입니다. 자세한 내용은 작업 등급 선택을 참조하세요.
  5. 리전을 클릭하여 CA의 위치를 선택합니다. 자세한 내용은 위치를 참조하세요.
  6. 선택사항: 초기화된 상태에서 생성 시점의 CA 상태를 선택합니다.
  7. 선택사항: 발급 시나리오 설정에서 인증서 프로필을 클릭하고 목록에서 요구사항에 가장 적합한 인증서 프로필을 선택합니다. 자세한 내용은 인증서 프로필을 참조하세요.
  8. 다음을 클릭합니다.
CA 주체 이름 구성
  1. 조직(O) 필드에 회사 이름을 입력합니다.
  2. 선택사항: 조직 단위(OU) 필드에 회사 부서 또는 사업부를 입력합니다.
  3. 선택사항: 국가 이름 필드에 2자리 국가 코드를 입력합니다.
  4. 선택사항: 주/도 이름 필드에 주 이름을 입력합니다.
  5. 선택사항: 지역 이름 필드에 도시 이름을 입력합니다.
  6. CA 일반 이름(CN) 필드에 CA 이름을 입력합니다.
  7. 풀 ID 필드에 CA 풀 이름을 입력합니다. CA를 만든 후에는 CA 풀을 변경할 수 없습니다.
  8. 다음을 클릭합니다.
CA 키 크기 및 알고리즘 구성
  1. 요구사항에 가장 부합하는 키 알고리즘을 선택합니다. 적절한 키 알고리즘 결정에 대한 자세한 내용은 키 알고리즘 선택을 참조하세요.
  2. 다음을 클릭합니다.
CA 아티팩트 구성

다음 단계는 선택사항입니다. 이 단계를 건너뛰면 기본 설정이 적용됩니다.

  1. Google 관리형 또는 자체 관리형 Cloud Storage 버킷 사용 여부를 선택합니다.
  2. 자체 관리형 Cloud Storage 버킷을 선택하지 않으면 CA Service는 CA와 동일한 위치에 Google 관리 버킷을 만듭니다.

  3. 해지 인증서 목록(CRL) 및 CA 인증서의 Cloud Storage 버킷 게시를 중지할지 여부를 선택합니다.
  4. CRL 및 CA 인증서의 Cloud Storage 버킷 게시는 기본적으로 사용 설정되어 있습니다. 이 설정을 중지하려면 전환 버튼을 클릭합니다.

  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 privateca pools 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 다운로드를 클릭하여 발급 CA가 서명할 수 있는 PEM 인코딩 CSR 파일을 다운로드합니다.

  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를 실행합니다.

다음 단계