gcpkms

package
v0.0.0-...-94a1697 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 4, 2024 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package gcpkms implements crypto.Signer and crypto.Decrypter backed by Google Cloud KMS.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Decrypter

type Decrypter struct {
	// contains filtered or unexported fields
}

Decrypter is backed by a supported Google cloud KMS asymmetric key. Only following key types are supported.

  • RSA_DECRYPT_OAEP_2048_SHA1
  • RSA_DECRYPT_OAEP_3072_SHA1
  • RSA_DECRYPT_OAEP_4096_SHA1
  • RSA_DECRYPT_OAEP_2048_SHA256
  • RSA_DECRYPT_OAEP_3072_SHA256
  • RSA_DECRYPT_OAEP_4096_SHA256
  • RSA_DECRYPT_OAEP_4096_SHA512

At minimum, following IAM permissions are required.

  • cloudkms.cryptoKeyVersions.get
  • cloudkms.cryptoKeyVersions.useToDecrypt
  • cloudkms.cryptoKeyVersions.viewPublicKey
  • cloudkms.locations.get
  • cloudkms.locations.list
  • resourcemanager.projects.get

Alternatively assign following roles. But it includes more permissions than absolutely required.

Example
package main

import (
	"context"
	"crypto/rand"
	"crypto/rsa"
	"fmt"

	"github.com/tprasadtp/cryptokms/gcpkms"
)

func main() {
	ctx := context.Background()

	// Key Version Resource name
	keyID := "projects/crypto-kms-integration-testing/locations/global/keyRings/itest-5/cryptoKeys/rsa-decrypt-oaep-4096-sha256/cryptoKeyVersions/1"

	// Create a new Decrypter
	decrypter, err := gcpkms.NewDecrypter(ctx, keyID)
	if err != nil {
		// TODO: Handle error
		panic(err)
	}

	// Message you want to encrypt
	// A nod to https://en.wikipedia.org/wiki/Stellar_classification.
	msg := []byte(`Oh Be A Fine Girl Kiss Me`)

	// This should not be really necessary as currently only asymmetric keys supported
	// for encryption are RSA keys.
	pub, ok := decrypter.Public().(*rsa.PublicKey)
	if !ok {
		// TODO: Handle error
		panic("not rsa key")
	}

	// Encrypt the message using public key.
	encrypted, err := rsa.EncryptOAEP(
		decrypter.HashFunc().New(),
		rand.Reader,
		pub,
		msg,
		nil,
	)
	if err != nil {
		// TODO: Handle error
		panic(err)
	}

	// Decrypt the message
	plaintext, err := decrypter.DecryptContext(ctx, nil, encrypted, &rsa.OAEPOptions{Hash: decrypter.HashFunc()})
	if err != nil {
		// TODO: Handle error
		panic(err)
	}

	fmt.Printf("Plaintext: %s", string(plaintext))
}
Output:

func NewDecrypter

func NewDecrypter(ctx context.Context, keyID string, opts ...option.ClientOption) (*Decrypter, error)

Returns a new Decrypter backed by GCP KMS asymmetric key.

func (*Decrypter) Algorithm

func (d *Decrypter) Algorithm() cryptokms.Algorithm

Algorithm returns KMS key algorithm. This only returns key algorithm.

func (*Decrypter) CreatedAt

func (d *Decrypter) CreatedAt() time.Time

CreatedAt time at which key/key material was created. This is time at which KMS key version was created, not the key material.

func (*Decrypter) Decrypt

func (d *Decrypter) Decrypt(rand io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) ([]byte, error)

This is a wrapper around DecryptContext.

func (*Decrypter) DecryptContext

func (d *Decrypter) DecryptContext(ctx context.Context, _ io.Reader, ciphertext []byte, opts crypto.DecrypterOpts) ([]byte, error)

DecryptContext decrypts the message with asymmetric key.

func (*Decrypter) HashFunc

func (d *Decrypter) HashFunc() crypto.Hash

HashFunc returns the hash algorithm used for computing the digest.

func (*Decrypter) Public

func (d *Decrypter) Public() crypto.PublicKey

Public returns the public key for the decrypter.

func (*Decrypter) WithContext

func (d *Decrypter) WithContext(ctx context.Context) *Decrypter

WithContext adds the given context to the decrypter.

type Signer

type Signer struct {
	// contains filtered or unexported fields
}

Signer is backed by supported Google cloud KMS asymmetric key. RSA_SIGN_PSS_* and RSA_SIGN_RAW_* keys are not supported.

Example
package main

import (
	"context"

	"github.com/tprasadtp/cryptokms"
	"github.com/tprasadtp/cryptokms/gcpkms"
)

func main() {
	ctx := context.Background()

	// Key Version Resource name.
	keyID := "projects/crypto-kms-integration-testing/locations/global/keyRings/itest-5/cryptoKeys/ec-sign-p384-sha384/cryptoKeyVersions/1"

	// Create a new Signer.
	signer, err := gcpkms.NewSigner(ctx, keyID)
	if err != nil {
		// TODO: Handle error
		panic(err)
	}

	// Message you want to sign
	// A nod to https://en.wikipedia.org/wiki/Stellar_classification.
	msg := []byte(`Oh Be A Fine Girl Kiss Me`)

	// hash the message you want to sign.
	// with defined hash function.
	h := signer.HashFunc().New()
	h.Write(msg)
	digest := h.Sum(nil)

	// Sign the digest
	signature, err := signer.SignContext(ctx, nil, digest, signer)
	if err != nil {
		// TODO: Handle error
		panic(err)
	}

	// Verify the signature
	err = cryptokms.VerifyDigestSignature(signer.Public(), signer.HashFunc(), digest, signature)
	if err != nil {
		// TODO: Handle error
		panic(err)
	}
}
Output:

func NewSigner

func NewSigner(ctx context.Context, keyID string, opts ...option.ClientOption) (*Signer, error)

Returns a new signer backed by GCP KMS asymmetric key. Only following key types are supported.

  • EC_SIGN_P256_SHA256
  • EC_SIGN_P384_SHA384
  • RSA_SIGN_PKCS1_2048_SHA256
  • RSA_SIGN_PKCS1_3072_SHA256
  • RSA_SIGN_PKCS1_4096_SHA256
  • RSA_SIGN_PKCS1_4096_SHA512

At minimum, following IAM permissions are required.

  • cloudkms.cryptoKeyVersions.get
  • cloudkms.cryptoKeyVersions.useToSign
  • cloudkms.cryptoKeyVersions.viewPublicKey
  • cloudkms.locations.get
  • cloudkms.locations.list
  • resourcemanager.projects.get

Alternatively assign following roles. But it includes more permissions than absolutely required.

func (*Signer) Algorithm

func (s *Signer) Algorithm() cryptokms.Algorithm

Algorithm returns KMS key algorithm. This only returns key algorithm.

func (*Signer) CreatedAt

func (s *Signer) CreatedAt() time.Time

CreatedAt time at which key was created. This is time at which KMS key version was created, not the key material.

func (*Signer) HashFunc

func (s *Signer) HashFunc() crypto.Hash

HashFunc returns the hash algorithm used for computing the digest.

func (*Signer) Public

func (s *Signer) Public() crypto.PublicKey

Public returns the public key for the signer.

func (*Signer) Sign

func (s *Signer) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)

This is a wrapper around SignContext.

func (*Signer) SignContext

func (s *Signer) SignContext(ctx context.Context, _ io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)

SignContext signs the digest with asymmetric key. Due to nature of GCP KMS, crypto.SignerOpts must match key's algorithm or it must be nil.

func (*Signer) WithContext

func (s *Signer) WithContext(ctx context.Context) *Signer

WithContext adds the given context to the signer.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL