Como recuperar uma chave pública

É possível recuperar a parte da chave pública de uma versão de chave assimétrica usando o Console do Google Cloud Platform, a ferramenta de linha de comando gcloud e a API Cloud KMS.

A chave pública está no formato Privacy-enhanced Electronic Mail (PEM). Para mais informações, consulte as seções do RFC 7468 que abordam as Considerações gerais e a Codificação textual de informações de chave pública do assunto (todos os links em inglês).

O usuário ou serviço que recupera a chave pública requer a permissão cloudkms.cryptoKeyVersions.viewPublicKey na versão da chave. Saiba sobre as permissões na versão Beta do Cloud KMS em Permissões e papéis.

Console

Para fazer o download da chave pública de uma versão de chave assimétrica atual, faça o seguinte:

  1. Abra a página Chaves de criptografia no Console do GCP.
  2. Clique no nome do keyring que contém a chave assimétrica.
  3. Clique no nome da chave que contém a versão dela.
  4. Para a versão da chave da qual você quer recuperar a chave pública, clique no ícone Mais (três pontos verticais).
  5. Clique em Conseguir chave pública. A chave pública é exibida. Copie-a para a área de transferência ou faça o download dela. Se a opção Ver chave pública não for exibida, confirme se ela é uma chave assimétrica e se você tem a permissão cloudkms.cryptoKeyVersions.viewPublicKey.

    Chave pública

O nome do arquivo de uma chave pública salvo do Console do GCP tem o formato [KEY_RING]-[KEY]-[CRYPTO_KEY_VERSION].pub.

Linha de comando

gcloud kms keys versions \
  get-public-key CRYPTO_KEY_VERSION \
  --location LOCATION \
  --keyring KEY_RING \
  --key KEY \
  --output-file ~/mykey.pub

API

Recupere a chave pública chamando o método CryptoKeyVersions.getPublicKey.

Especifique o ID do recurso da versão da chave pública que você quer recuperar.

Go

import (
	"context"
	"crypto/x509"
	"encoding/pem"
	"fmt"

	cloudkms "cloud.google.com/go/kms/apiv1"
	kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
)

// getAsymmetricPublicKey retrieves the public key from a saved asymmetric key pair on KMS.
func getAsymmetricPublicKey(name string) (interface{}, error) {
	// name: "projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys/KEY_ID/cryptoKeyVersions/1"
	ctx := context.Background()
	client, err := cloudkms.NewKeyManagementClient(ctx)
	if err != nil {
		return nil, fmt.Errorf("cloudkms.NewKeyManagementClient: %v", err)
	}

	// Build the request.
	req := &kmspb.GetPublicKeyRequest{
		Name: name,
	}
	// Call the API.
	response, err := client.GetPublicKey(ctx, req)
	if err != nil {
		return nil, fmt.Errorf("GetPublicKey: %v", err)
	}
	// Parse the key.
	keyBytes := []byte(response.Pem)
	block, _ := pem.Decode(keyBytes)
	publicKey, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		return nil, fmt.Errorf("x509.ParsePKIXPublicKey: %v", err)
	}
	return publicKey, nil
}

Java

/**
 * Retrieves the public key from a saved asymmetric key pair on Cloud KMS
 *
 * Example keyName:
 *   "projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys/KEY_ID/cryptoKeyVersions/1"
 */
public static PublicKey getAsymmetricPublicKey(String keyName)
    throws IOException, GeneralSecurityException {

  // Create the Cloud KMS client.
  try (KeyManagementServiceClient client = KeyManagementServiceClient.create()) {
    com.google.cloud.kms.v1.PublicKey pub = client.getPublicKey(keyName);

    // Convert a PEM key to DER without taking a dependency on a third party library
    String pemKey = pub.getPem();
    pemKey = pemKey.replaceFirst("-----BEGIN PUBLIC KEY-----", "");
    pemKey = pemKey.replaceFirst("-----END PUBLIC KEY-----", "");
    pemKey = pemKey.replaceAll("\\s", "");
    byte[] derKey = BaseEncoding.base64().decode(pemKey);

    X509EncodedKeySpec keySpec = new X509EncodedKeySpec(derKey);

    if (pub.getAlgorithm().name().contains("RSA")) {
      return KeyFactory.getInstance("RSA").generatePublic(keySpec);
    } else if (pub.getAlgorithm().name().contains("EC")) {
      return KeyFactory.getInstance("EC").generatePublic(keySpec);
    } else {
      throw new UnsupportedOperationException(String.format(
          "key at path '%s' is of unsupported type '%s'.", keyName, pub.getAlgorithm()));
    }
  }
}

Python

def get_asymmetric_public_key(key_name):
    """
    Retrieves the public key from a saved asymmetric key pair on Cloud KMS

    Example key_name:
      "projects/PROJECT_ID/locations/global/keyRings/RING_ID/cryptoKeys\
              /KEY_ID/cryptoKeyVersions/1"

    Requires:
      cryptography.hazmat.backends.default_backend
      cryptography.hazmat.primitives.serialization
    """

    client = kms_v1.KeyManagementServiceClient()
    response = client.get_public_key(key_name)

    key_txt = response.pem.encode('ascii')
    key = serialization.load_pem_public_key(key_txt, default_backend())
    return key