azcrypto

package module
v1.0.1 Latest Latest
Warning

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

Go to latest
Published: Oct 16, 2023 License: MIT Imports: 11 Imported by: 0

README

Cryptography Client for Azure Key Vault

reference ci codecov

This module provides a cryptography client for the Azure Key Vault Keys client module for Go. This project is not supported by the Azure SDK team, but does align with the cryptography clients in other supported languages like the CryptographyClient I wrote for the Azure SDK for .NET. See related projects for more information.

Getting started

Install packages

Install azcrypto and azidentity with go get:

go get github.com/heaths/azcrypto
go get github.com/Azure/azure-sdk-for-go/sdk/azidentity

azidentity is used for Azure Active Directory authentication as demonstrated below.

Prerequisites
Authentication

This document demonstrates using azidentity.NewDefaultAzureCredential to authenticate. This credential type works in both local development and production environments. We recommend using a managed identity in production.

NewClient accepts any azcore.TokenCredential including those from azidentity. See the azidentity documentation for more information about other credential types.

Create a client

Constructing the client requires your key's URL, called a key ID, which you can get from the Azure Portal or Azure CLI. You should store this key ID including the version used to encrypt, sign, or wrap with your data to make sure you can decrypt, verify, and unwrap.

import (
    "github.com/Azure/azure-sdk-for-go/sdk/azidentity"
    "github.com/heaths/azcrypto"
)

func main() {
    cred, err := azidentity.NewDefaultAzureCredential(nil)
    if err != nil {
        // TODO: handle error
    }

    client, err := azcrypto.NewClient(
        "https://{vault-name}.vault.azure.net/keys/{key-name}/{key-version}",
        cred,
        nil,
    )
    if err != nil {
        // TODO: handle error
    }
}

You can also create a Client from a JSON Web Key (JWK) using NewClientFromJSONWebKey. No attempt to connect to Azure Key Vault or Managed HSM will be made.

Key concepts

The Client will attempt to download the specified public key when first used. This will improve throughput while reducing the risk of getting throttled by Key Vault's rate limits.

Encrypt and decrypt

You can encrypt with a public key, but decryption requires a private key to which Azure Key Vault or Managed HSM does not provide access. The following encryption operation will be performed locally if the caller has the keys/get data action permission, and decrypted remotely.

import (
    "context"

    "github.com/heaths/azcrypto"
)

func encryptAndDecrypt(client *azcrypto.Client, plaintext string) (string, error) {
    encryptResult, err := client.Encrypt(
        context.TODO(),
        azcrypto.EncryptAlgorithmRSAOAEP256,
        []byte(plaintext),
        nil,
    )
    if err != nil {
        return "", err
    }

    decryptResult, err := client.Decrypt(
        context.TODO(),
        azcrypto.EncryptAlgorithmRSAOAEP256,
        encryptResult.Ciphertext,
        nil,
    )
    if err != nil {
        return "", err
    }

    return string(decryptResult.Plaintext), nil
}
Sign and verify

You can verify a signature with a public key, but signing requires a private key to which Azure Key Vault or Managed HSM does not provide access. The following signing operation will be performed on Key Vault or Managed HSM, but verification will be performed locally if the caller has the keys/get data action permission.

import (
    "context"
    "crypto/sha256"

    "github.com/heaths/azcrypto"
)

func signAndVerify(client *azcrypto.Client, plaintext string) (bool, error) {
    // Performed remotely by Azure Key Vault or Managed HSM.
    signResult, err := client.SignData(
        context.TODO(),
        azcrypto.SignAlgorithmES256,
        []byte(plaintext),
        nil,
    )
    if err != nil {
        return false, err
    }

    // Performed locally if the public key could be retrieved.
    verifyResult, err := client.VerifyData(
        context.TODO(),
        signResult.Algorithm,
        []byte(plaintext),
        signResult.Signature,
        nil,
    )
    if err != nil {
        return false, err
    }

    return verifyResult.Valid, nil
}
Key wrap and unwrap

You can wrap a key - typically a key used for symmetric algorithms such as AES - with a public key, but unwrapping the key requires a private key to which Azure Key Vault or Managed HSM does not provide access. The following wrapping operation will be performed locally if the caller has the keys/get data action permission, and unwrapped remotely on Key Vault or Managed HSM.

This is useful for keeping symmetric algorithm keys such as AES secure while taking advantage of symmetric keys' speed for use in block ciphers.

import (
    "context"

    "github.com/heaths/azcrypto"
)

func wrapAndUnwrapKey(client *azcrypto.Client, key []byte) ([]byte, error) {
    wrappedKey, err := client.WrapKey(
        context.TODO(),
        azcrypto.WrapKeyAlgorithmRSAOAEP256,
        key,
        nil,
    )
    if err != nil {
        return nil, err
    }

    unwrappedKey, err := client.Decrypt(
        context.TODO(),
        azcrypto.WrapKeyAlgorithmRSAOAEP256,
        wrappedKey.EncryptedKey,
        nil,
    )
    if err != nil {
        return nil, err
    }

    return unwrappedKey.Key, nil
}

Examples

Get started with our examples.

Though not officially part of the Azure SDKs, this module was developed using the same guidelines. Convenience methods have been added to help call cryptographic key operations correctly, as well as support for caching public keys when permitted, and using a JWK in scenarios it may be stored as an Azure Key Vault secret.

For more information about the other Key Vault SDKs, see https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/security/keyvault or, for individual packages:

License

Licensed under the MIT license.

Documentation

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Client

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

Client defines helpful methods to perform cryptography operations against a specific keyID, which should be stored with your data and used to perform the reverse cryptographic operations.

func NewClient

func NewClient(keyID string, credential azcore.TokenCredential, options *ClientOptions) (*Client, error)

NewClient creates a Client for a specified key ID. If the caller has permission to download the specified public key, supported cryptography operations are performed locally.

The public key is fetched only once. If you use a key ID without a version (not generally recommended) and the key is rotated in Azure Key Vault or Managed HSM, a new version is not retrieved. It is recommended that you always specify a key ID with a version, however, or at least store the full key ID returned by the service with your data so you always know which key to use to reverse the operation e.g., you can decrypt data you previously encrypted.

Example
package main

import (
	"encoding/json"

	"github.com/Azure/azure-sdk-for-go/sdk/azidentity"
	"github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys"
	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	keyID := "https://{vault-name}.vault.azure.net/keys/{key-name}/{key-version}"
	cred, err := azidentity.NewDefaultAzureCredential(nil)
	if err != nil {
		// TODO: handle error
	}

	client, err := azcrypto.NewClient(keyID, cred, nil)
	if err != nil {
		// TODO: handle error
	}

	_ = client
}

func init() {

	const jwk = `{
		"kty": "oct",
		"k": "vzZ5FtPDDpVJCwdwikXfzvz_3RAhWqGg7mcpPqPRlXk"
	}`

	var kek azkeys.JSONWebKey
	err := json.Unmarshal([]byte(jwk), &kek)
	if err != nil {
		panic(err)
	}

	options := azcrypto.ClientOptions{

		Rand: new(rng),
	}
	client, err = azcrypto.NewClientFromJSONWebKey(kek, &options)
	if err != nil {
		panic(err)
	}

}

// rng is a mock RNG used only for testing.
type rng struct{}

func (r *rng) Read(b []byte) (int, error) {
	for i := range b {
		b[i] = byte(i)
	}
	return len(b), nil
}
Output:

func NewClientFromJSONWebKey added in v0.7.0

func NewClientFromJSONWebKey(key azkeys.JSONWebKey, options *ClientOptions) (*Client, error)

NewClientFromJSONWebKey creates a Client from the given JSON Web Key (JWK). No attempt will be made to contact Azure Key Vault or Managed HSM. If the JWK does not have the key material necessary for an operation, an error will be returned.

Example
package main

import (
	"encoding/json"

	"github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys"
	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	// Load an AES key encryption key (KEK) from a JWK.
	const jwk = `{
		"kty": "oct",
		"k": "vzZ5FtPDDpVJCwdwikXfzvz_3RAhWqGg7mcpPqPRlXk"
	}`

	var kek azkeys.JSONWebKey
	err := json.Unmarshal([]byte(jwk), &kek)
	if err != nil {
		// TODO: handle error
	}

	client, err := azcrypto.NewClientFromJSONWebKey(kek, nil)
	if err != nil {
		// TODO: handle error
	}

	_ = client
}

func init() {

	const jwk = `{
		"kty": "oct",
		"k": "vzZ5FtPDDpVJCwdwikXfzvz_3RAhWqGg7mcpPqPRlXk"
	}`

	var kek azkeys.JSONWebKey
	err := json.Unmarshal([]byte(jwk), &kek)
	if err != nil {
		panic(err)
	}

	options := azcrypto.ClientOptions{

		Rand: new(rng),
	}
	client, err = azcrypto.NewClientFromJSONWebKey(kek, &options)
	if err != nil {
		panic(err)
	}

}

// rng is a mock RNG used only for testing.
type rng struct{}

func (r *rng) Read(b []byte) (int, error) {
	for i := range b {
		b[i] = byte(i)
	}
	return len(b), nil
}
Output:

func (*Client) Decrypt added in v0.3.0

func (client *Client) Decrypt(ctx context.Context, algorithm EncryptAlgorithm, ciphertext []byte, options *DecryptOptions) (DecryptResult, error)

Decrypt decrypts the ciphertext using the specified algorithm.

Example
package main

import (
	"context"
	"encoding/base64"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	decoder := base64.RawURLEncoding
	ciphertext, err := decoder.DecodeString("{base64url ciphertext}")
	if err != nil {
		// TODO: handle error
	}

	result, err := client.Decrypt(context.TODO(), azcrypto.EncryptAlgorithmRSAOAEP256, ciphertext, nil)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Plaintext: %x\n", result.Plaintext)
}
Output:

func (*Client) DecryptAESCBC added in v0.5.0

func (client *Client) DecryptAESCBC(ctx context.Context, algorithm EncryptAESCBCAlgorithm, ciphertext, iv []byte, options *DecryptAESCBCOptions) (DecryptAESCBCResult, error)

DecryptAESCBC decrypts the ciphertext using the specified algorithm.

Example

This example demonstrates how to decrypt using AES-CBC.

You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.

package main

import (
	"context"
	"crypto/aes"
	"encoding/base64"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	ciphertext, err := base64.StdEncoding.DecodeString("AAECAwQFBgcICQoLDA0OD3zQDBEoBTQX072KcqE9PwE=")
	if err != nil {
		// TODO: handle error
	}

	// Common practice is to prepend the unique IV for each block chain to the ciphertext.
	// Reverse what we did in the corresponding encryption example.
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	result, err := client.DecryptAESCBC(context.TODO(), azcrypto.EncryptAESCBCAlgorithmA128CBC, ciphertext, iv, nil)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Plaintext: %s\n", base64.StdEncoding.EncodeToString(result.Plaintext))

}
Output:

Plaintext: YWJjZGVmZ2hpamtsbW5vcA==
Example (Authenticated)

This example demonstrates how to decrypt ciphertext using AES-CBC with an authenticating HMAC-SHA256.

package main

import (
	"bytes"
	"context"
	"crypto/aes"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	ciphertext, err := base64.StdEncoding.DecodeString("AAECAwQFBgcICQoLDA0OD3zQDBEoBTQX072KcqE9PwEKzV0T+fWqPvkc8kRDtZPZDUJcCoH6T7l6EZtk1vZE2A==")
	if err != nil {
		// TODO: handle error
	}

	// Get the SHA256 hash from the end of the ciphertext we appended in the corresponding encryption example.
	signature := ciphertext[len(ciphertext)-sha256.Size:]
	ciphertext = ciphertext[:len(ciphertext)-sha256.Size]

	// Load your key for generating HMAC.
	key, err := base64.StdEncoding.DecodeString("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=")
	if err != nil {
		// TODO: handle error
	}

	// Compute the signature and compare with our extracted signature.
	h := hmac.New(sha256.New, key)
	h.Write(ciphertext)
	if !bytes.Equal(signature, h.Sum(nil)) {
		// TODO: handle error
	}

	// Common practice is to prepend the unique IV for each block chain to the ciphertext.
	// Reverse what we did in the corresponding encryption example.
	iv := ciphertext[:aes.BlockSize]
	ciphertext = ciphertext[aes.BlockSize:]

	result, err := client.DecryptAESCBC(context.TODO(), azcrypto.EncryptAESCBCAlgorithmA128CBC, ciphertext, iv, nil)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Plaintext: %s\n", base64.StdEncoding.EncodeToString(result.Plaintext))

}
Output:

Plaintext: YWJjZGVmZ2hpamtsbW5vcA==

func (*Client) DecryptAESGCM added in v0.5.0

func (client *Client) DecryptAESGCM(ctx context.Context, algorithm EncryptAESGCMAlgorithm, ciphertext, nonce, authenticationTag, additionalAuthenticatedData []byte, options *DecryptAESGCMOptions) (DecryptAESGCMResult, error)

DecryptAESGCM decrypts the ciphertext using the specified algorithm.

Example
package main

import (
	"context"
	"encoding/hex"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	// Read ciphertext, nonce, and authentication tag, along with optional additional authenticated data (AAD).
	// AAD is not itself encrypted, but used in the encryption process and needs to be passed to DecryptAESGCM.
	ciphertext, err := hex.DecodeString("fb6b11820810c6c5af")
	if err != nil {
		// TODO: handle error
	}
	nonce, err := hex.DecodeString("000102030405060708090a0b")
	if err != nil {
		// TODO: handle error
	}
	authenticationTag, err := hex.DecodeString("22b2431748c3f81679ebe04f9d11fbae")
	if err != nil {
		// TODO: handle error
	}
	var additionalAuthenticatedData []byte

	result, err := client.DecryptAESGCM(
		context.TODO(),
		azcrypto.EncryptAESGCMAlgorithmA128GCM,
		ciphertext,
		nonce,
		authenticationTag,
		additionalAuthenticatedData,
		nil,
	)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Plaintext: %s\n", result.Plaintext)

}
Output:

Plaintext: plaintext

func (*Client) Encrypt added in v0.3.0

func (client *Client) Encrypt(ctx context.Context, algorithm EncryptAlgorithm, plaintext []byte, options *EncryptOptions) (EncryptResult, error)

Encrypt encrypts the plaintext using the specified algorithm.

Example
package main

import (
	"context"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	result, err := client.Encrypt(context.TODO(), azcrypto.EncryptAlgorithmRSAOAEP256, []byte("plaintext"), nil)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Ciphertext: %x\n", result.Ciphertext)
}
Output:

func (*Client) EncryptAESCBC added in v0.5.0

func (client *Client) EncryptAESCBC(ctx context.Context, algorithm EncryptAESCBCAlgorithm, plaintext, iv []byte, options *EncryptAESCBCOptions) (EncryptAESCBCResult, error)

EncryptAESCBC encrypts the plaintext using the specified algorithm and optional initialization vector (IV). If iv is nil, one will be generated from a cryptographically secure random number generator, or options.Rand if specified.

You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.

Example

This example demonstrates how to encrypt plaintext using AES-CBC. The plaintext length must be a multiple of the key encryption key (KEK) block size. You can use PKCS7 padding if necessary.

You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.

package main

import (
	"context"
	"encoding/base64"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	// Use a unique initialization vector (IV) using a cryptographically random number generator for each block chain.
	// If nil, one will be generated for you using crypto/rand.Reader.
	var iv []byte

	// Plaintext length must be a multiple of the AES key encryption key (KEK) block size.
	// Use PKCS7 padding if necessary.
	plaintext, err := base64.StdEncoding.DecodeString("YWJjZGVmZ2hpamtsbW5vcA==")
	if err != nil {
		// TODO: handle error
	}

	result, err := client.EncryptAESCBC(context.TODO(), azcrypto.EncryptAESCBCAlgorithmA128CBC, plaintext, iv, nil)
	if err != nil {
		// TODO: handle error
	}

	// Common practice to prepend the IV (does not need to be secret) to the ciphertext.
	ciphertext := append(result.IV, result.Ciphertext...)
	fmt.Printf("IV + ciphertext: %s\n", base64.StdEncoding.EncodeToString(ciphertext))

}
Output:

IV + ciphertext: AAECAwQFBgcICQoLDA0OD3zQDBEoBTQX072KcqE9PwE=
Example (Authenticated)

This example demonstrates how to encrypt plaintext using AES-CBC with an authenticating HMAC-SHA256. The plaintext length must be a multiple of the key encryption key (KEK) block size. You can use PKCS7 padding if necessary.

package main

import (
	"context"
	"crypto/hmac"
	"crypto/sha256"
	"encoding/base64"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	// Use a unique initialization vector (IV) using a cryptographically random number generator for each block chain.
	// If nil, one will be generated for you using crypto/rand.Reader.
	var iv []byte

	// Plaintext length must be a multiple of the AES key encryption key (KEK) block size.
	// Use PKCS7 padding if necessary.
	plaintext, err := base64.StdEncoding.DecodeString("YWJjZGVmZ2hpamtsbW5vcA==")
	if err != nil {
		// TODO: handle error
	}

	result, err := client.EncryptAESCBC(context.TODO(), azcrypto.EncryptAESCBCAlgorithmA128CBC, plaintext, iv, nil)
	if err != nil {
		// TODO: handle error
	}

	// Prepend the IV (does not need to be secret) to the ciphertext.
	ciphertext := append(result.IV, result.Ciphertext...)

	// Load your key for generating HMAC.
	key, err := base64.StdEncoding.DecodeString("AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8=")
	if err != nil {
		// TODO: handle error
	}

	h := hmac.New(sha256.New, key)
	h.Write(ciphertext)

	// Append the HMAC to the ciphertext.
	ciphertext = h.Sum(ciphertext)
	fmt.Printf("HMAC-SHA256(IV + ciphertext): %s\n", base64.StdEncoding.EncodeToString(ciphertext))

}
Output:

HMAC-SHA256(IV + ciphertext): AAECAwQFBgcICQoLDA0OD3zQDBEoBTQX072KcqE9PwEKzV0T+fWqPvkc8kRDtZPZDUJcCoH6T7l6EZtk1vZE2A==

func (*Client) EncryptAESGCM added in v0.5.0

func (client *Client) EncryptAESGCM(ctx context.Context, algorithm EncryptAESCBCAlgorithm, plaintext, additionalAuthenticatedData []byte, options *EncryptAESGCMOptions) (EncryptAESGCMResult, error)

EncryptAESGCM encrypts the plaintext using the specified algorithm and optional authenticated data which is not encrypted.

Example
package main

import (
	"context"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	// Read plaintext and optional additional authenticated data (AAD).
	// AAD is not itself encrypted, but used in the encryption process and needs to be passed to DecryptAESGCM.
	plaintext := []byte("plaintext")
	var additionalAuthenticatedData []byte

	// A unique nonce will be generated using a cryptographically random number generator for each block chain.
	result, err := client.EncryptAESGCM(
		context.TODO(),
		azcrypto.EncryptAESGCMAlgorithmA128GCM,
		plaintext,
		additionalAuthenticatedData,
		nil,
	)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Ciphertext: %x\n", result.Ciphertext)
	fmt.Printf("Nonce: %x\n", result.Nonce)
	fmt.Printf("Authentication tag: %x\n", result.AuthenticationTag)

}
Output:

Ciphertext: fb6b11820810c6c5af
Nonce: 000102030405060708090a0b
Authentication tag: 22b2431748c3f81679ebe04f9d11fbae

func (*Client) KeyID

func (client *Client) KeyID() string

KeyID gets the key ID passed to NewClient.

func (*Client) Sign

func (client *Client) Sign(ctx context.Context, algorithm SignAlgorithm, digest []byte, options *SignOptions) (SignResult, error)

Sign signs the specified digest using the specified algorithm.

Example
package main

import (
	"context"
	"crypto/sha256"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	hash := sha256.New()
	hash.Write([]byte("plaintext"))
	digest := hash.Sum(nil)

	result, err := client.Sign(context.TODO(), azcrypto.SignAlgorithmES256, digest, nil)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Signature: %x\n", result.Signature)
}
Output:

func (*Client) SignData added in v0.3.0

func (client *Client) SignData(ctx context.Context, algorithm SignAlgorithm, data []byte, options *SignDataOptions) (SignResult, error)

SignData hashes the data using a suitable hash based on the specified algorithm.

Example
package main

import (
	"context"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	result, err := client.SignData(context.TODO(), azcrypto.SignAlgorithmES256, []byte("plaintext"), nil)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Signature: %x\n", result.Signature)
}
Output:

func (*Client) UnwrapKey added in v0.4.0

func (client *Client) UnwrapKey(ctx context.Context, algorithm WrapKeyAlgorithm, encryptedKey []byte, options *UnwrapKeyOptions) (UnwrapKeyResult, error)

UnwrapKey decrypts the specified key using the specified algorithm. Asymmetric decryption is typically used to unwrap a symmetric key used for streaming ciphers.

Example
package main

import (
	"context"
	"encoding/base64"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	decoder := base64.RawURLEncoding
	encryptedKey, err := decoder.DecodeString("{base64url key}")
	if err != nil {
		// TODO: handle error
	}

	// Decrypt the key for use as a block cipher for e.g., streaming data.
	result, err := client.UnwrapKey(context.TODO(), azcrypto.WrapKeyAlgorithmRSAOAEP256, encryptedKey, nil)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Decrypted key: %x\n", result.Key)
}
Output:

func (*Client) Verify

func (client *Client) Verify(ctx context.Context, algorithm SignAlgorithm, digest, signature []byte, options *VerifyOptions) (VerifyResult, error)

Verify verifies that the specified digest is valid using the specified signature and algorithm.

Example
package main

import (
	"context"
	"encoding/base64"
	"fmt"

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	decoder := base64.RawURLEncoding
	signature, err := decoder.DecodeString("{base64url signature}")
	if err != nil {
		// TODO: handle error
	}

	result, err := client.VerifyData(context.TODO(), azcrypto.SignAlgorithmES256, []byte("plaintext"), signature, nil)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Valid: %t\n", result.Valid)
}
Output:

func (*Client) VerifyData added in v0.3.0

func (client *Client) VerifyData(ctx context.Context, algorithm SignAlgorithm, data, signature []byte, options *VerifyDataOptions) (VerifyResult, error)

VerifyData verifies the digest of the data is valid using a suitable hash based on the specified algorithm.

func (*Client) WrapKey added in v0.4.0

func (client *Client) WrapKey(ctx context.Context, algorithm WrapKeyAlgorithm, key []byte, options *WrapKeyOptions) (WrapKeyResult, error)

WrapKey encrypts the specified key using the specified algorithm. Asymmetric encryption is typically used to wrap a symmetric key used for streaming ciphers.

Example
package main

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

	"github.com/heaths/azcrypto"
)

var client *azcrypto.Client

func main() {
	// Generate AES-256 key using a cryptographically secure RNG.
	key := make([]byte, 32)
	_, err := rand.Read(key)
	if err != nil {
		// TODO: handle error
	}

	// Encrypt the key using RSA-OAEP-256 to be stored securely.
	result, err := client.WrapKey(context.TODO(), azcrypto.WrapKeyAlgorithmRSAOAEP256, key, nil)
	if err != nil {
		// TODO: handle error
	}

	fmt.Printf("Encrypted key: %x\n", result.EncryptedKey)
}
Output:

type ClientOptions

type ClientOptions struct {
	azkeys.ClientOptions

	// Rand should be a cryptographically random number generator.
	// The default is crypto/Rand.Reader.
	Rand io.Reader
	// contains filtered or unexported fields
}

type DecryptAESCBCOptions added in v0.5.0

type DecryptAESCBCOptions struct {
	azkeys.DecryptOptions
}

DecryptAESCBCOptions defines options for the DecryptAESCBC method.

type DecryptAESCBCResult added in v0.5.0

type DecryptAESCBCResult = alg.DecryptResult

DecryptAESCBCResult contains information returned by the DecryptAESCBC method.

type DecryptAESGCMOptions added in v0.5.0

type DecryptAESGCMOptions struct {
	azkeys.DecryptOptions
}

DecryptAESGCMOptions defines options for the DecryptAESGCM method.

type DecryptAESGCMResult added in v0.5.0

type DecryptAESGCMResult = alg.DecryptResult

DecryptAESGCMResult contains information returned by the DecryptAESGCM method.

type DecryptOptions added in v0.3.0

type DecryptOptions struct {
	azkeys.DecryptOptions
}

DecryptOptions defines options for the Decrypt method.

type DecryptResult added in v0.3.0

type DecryptResult = alg.DecryptResult

DecryptResult contains information returned by the Decrypt method.

type EncryptAESCBCAlgorithm added in v0.5.0

type EncryptAESCBCAlgorithm = alg.EncryptAESCBCAlgorithm

EncryptAESCBCAlgorithm defines the encryption algorithms supported by Azure Managed HSM for encryption with AES-CBC.

You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.

const (
	// EncryptAESCBCAlgorithmA128CBC uses A128-CBC with a message length appropriately padded to a multiple of 16 bytes.
	//
	// You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.
	EncryptAESCBCAlgorithmA128CBC EncryptAESCBCAlgorithm = azkeys.EncryptionAlgorithmA128CBC

	// EncryptAESCBCAlgorithmA128CBC uses A128-CBCPAD to pad a message using PKCS7 to a multiple of 16 bytes.
	//
	// You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.
	EncryptAESCBCAlgorithmA128CBCPAD EncryptAESCBCAlgorithm = azkeys.EncryptionAlgorithmA128CBCPAD

	// EncryptAESCBCAlgorithmA192CBC uses A192-CBC with a message length appropriately padded to a multiple of 16 bytes.
	//
	// You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.
	EncryptAESCBCAlgorithmA192CBC EncryptAESCBCAlgorithm = azkeys.EncryptionAlgorithmA192CBC

	// EncryptAESCBCAlgorithmA192CBC uses A192-CBCPAD to pad a message using PKCS7 to a multiple of 16 bytes.
	//
	// You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.
	EncryptAESCBCAlgorithmA192CBCPAD EncryptAESCBCAlgorithm = azkeys.EncryptionAlgorithmA192CBCPAD

	// EncryptAESCBCAlgorithmA256CBC uses A256-CBC with a message length appropriately padded to a multiple of 16 bytes.
	//
	// You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.
	EncryptAESCBCAlgorithmA256CBC EncryptAESCBCAlgorithm = azkeys.EncryptionAlgorithmA256CBC

	// EncryptAESCBCAlgorithmA256CBC uses A256-CBCPAD to pad a message using PKCS7 to a multiple of 16 bytes.
	//
	// You should not use CBC without first ensuring the integrity of the ciphertext using an HMAC.
	EncryptAESCBCAlgorithmA256CBCPAD EncryptAESCBCAlgorithm = azkeys.EncryptionAlgorithmA256CBCPAD
)

type EncryptAESCBCOptions added in v0.5.0

type EncryptAESCBCOptions struct {
	azkeys.EncryptOptions
}

EncryptAESCBCOptions defines options for the EncryptAESCBC method.

type EncryptAESCBCResult added in v0.5.0

type EncryptAESCBCResult struct {
	// Algorithm is encryption algorithm used to encrypt.
	Algorithm EncryptAlgorithm

	// KeyID is the key ID used to encrypt. This key ID should be retained.
	KeyID string

	// Ciphertext is the encryption result.
	Ciphertext []byte

	// IV is the initialization vector used to encrypt using AES-CBC.
	IV []byte
}

EncryptAESCBCResult contains information returned by the EncryptAESCBC method.

type EncryptAESGCMAlgorithm added in v0.5.0

type EncryptAESGCMAlgorithm = alg.EncryptAESGCMAlgorithm

EncryptAESGCMAlgorithm defines the encryption algorithms supported by Azure Managed HSM for encryption with AES-GCM.

const (
	// EncryptAESGCMAlgorithmA128GCM uses A128-GCM with optional authenticated data.
	EncryptAESGCMAlgorithmA128GCM EncryptAESGCMAlgorithm = azkeys.EncryptionAlgorithmA128GCM

	// EncryptAESGCMAlgorithmA192GCM uses A192-GCM with optional authenticated data.
	EncryptAESGCMAlgorithmA192GCM EncryptAESGCMAlgorithm = azkeys.EncryptionAlgorithmA192GCM

	// EncryptAESGCMAlgorithmA256GCM uses A256-GCM with optional authenticated data.
	EncryptAESGCMAlgorithmA256GCM EncryptAESGCMAlgorithm = azkeys.EncryptionAlgorithmA256GCM
)

type EncryptAESGCMOptions added in v0.5.0

type EncryptAESGCMOptions struct {
	azkeys.EncryptOptions
}

EncryptAESGCMOptions defines options for the EncryptAESGCM method.

type EncryptAESGCMResult added in v0.5.0

type EncryptAESGCMResult struct {
	// Algorithm is encryption algorithm used to encrypt.
	Algorithm EncryptAlgorithm

	// KeyID is the key ID used to encrypt. This key ID should be retained.
	KeyID string

	// Ciphertext is the encryption result.
	Ciphertext []byte

	// Nonce is the nonce used to encrypt using AES-GCM.
	Nonce []byte

	// AdditionalAuthenticatedData passed to EncryptAESGCM.
	AdditionalAuthenticatedData []byte

	// AuthenticationTag returned from EncryptAESGCM.
	AuthenticationTag []byte
}

EncryptAESGCMResult contains information returned by the EncryptAESGCM method.

type EncryptAlgorithm added in v0.5.0

type EncryptAlgorithm = alg.EncryptAlgorithm

EncryptAlgorithm defines the encryption algorithms supported by Azure Key Vault or Managed HSM.

const (
	// EncryptAlgorithmRSA15 uses RSA 1.5.
	EncryptAlgorithmRSA15 EncryptAlgorithm = azkeys.EncryptionAlgorithmRSA15

	// EncryptAlgorithmRSAOAEP uses RSA-OAEP.
	EncryptAlgorithmRSAOAEP EncryptAlgorithm = azkeys.EncryptionAlgorithmRSAOAEP

	// EncryptAlgorithmRSAOAEP256 uses RSA-OAEP-256.
	EncryptAlgorithmRSAOAEP256 EncryptAlgorithm = azkeys.EncryptionAlgorithmRSAOAEP256
)

type EncryptOptions added in v0.3.0

type EncryptOptions struct {
	azkeys.EncryptOptions
}

EncryptOptions defines options for the Encrypt method.

type EncryptResult added in v0.3.0

type EncryptResult struct {
	// Algorithm is encryption algorithm used to encrypt.
	Algorithm EncryptAlgorithm

	// KeyID is the key ID used to encrypt. This key ID should be retained.
	KeyID string

	// Ciphertext is the encryption result.
	Ciphertext []byte
}

EncryptResult contains information returned by the Encrypt method.

type SignAlgorithm added in v0.5.0

type SignAlgorithm = alg.SignAlgorithm

SignAlgorithm defines the signing algorithms supported by Azure Key Vault or Managed HSM.

const (
	// SignAlgorithmES256 uses the P-256 curve requiring a SHA-256 hash.
	SignAlgorithmES256 SignAlgorithm = azkeys.SignatureAlgorithmES256

	// SignAlgorithmES256K uses the P-256K curve requiring a SHA-256 hash.
	SignAlgorithmES256K SignAlgorithm = azkeys.SignatureAlgorithmES256K

	// SignAlgorithmES384 uses the P-384 curve requiring a SHA-384 hash.
	SignAlgorithmES384 SignAlgorithm = azkeys.SignatureAlgorithmES384

	// SignAlgorithmES512 uses the P-521 curve requiring a SHA-512 hash.
	SignAlgorithmES512 SignAlgorithm = azkeys.SignatureAlgorithmES512

	// SignAlgorithmPS256 uses RSASSA-PSS using a SHA-256 hash.
	SignAlgorithmPS256 SignAlgorithm = azkeys.SignatureAlgorithmPS256

	// SignAlgorithmPS384 uses RSASSA-PSS using a SHA-384 hash.
	SignAlgorithmPS384 SignAlgorithm = azkeys.SignatureAlgorithmPS384

	// SignAlgorithmPS512 uses RSASSA-PSS using a SHA-512 hash.
	SignAlgorithmPS512 SignAlgorithm = azkeys.SignatureAlgorithmPS512

	// SignAlgorithmRS256 uses RSASSA-PKCS1-v1_5 using a SHA256 hash.
	SignAlgorithmRS256 SignAlgorithm = azkeys.SignatureAlgorithmRS256

	// SignAlgorithmRS384 uses RSASSA-PKCS1-v1_5 using a SHA384 hash.
	SignAlgorithmRS384 SignAlgorithm = azkeys.SignatureAlgorithmRS384

	// SignAlgorithmRS512 uses RSASSA-PKCS1-v1_5 using a SHA512 hash.
	SignAlgorithmRS512 SignAlgorithm = azkeys.SignatureAlgorithmRS512
)

type SignDataOptions added in v0.3.0

type SignDataOptions struct {
	SignOptions
}

SignDataOptions defines options for the SignData method.

type SignOptions

type SignOptions struct {
	azkeys.SignOptions
}

SignOptions defines options for the Sign method.

type SignResult

type SignResult = alg.SignResult

SignResult contains information returned by the Sign method.

type UnwrapKeyOptions added in v0.4.0

type UnwrapKeyOptions struct {
	azkeys.UnwrapKeyOptions
}

UnwrapKeyOptions defines options for the UnwrapKey method.

type UnwrapKeyResult added in v0.4.0

type UnwrapKeyResult = alg.UnwrapKeyResult

UnwrapKeyResult contains information returned by the UnwrapKey method.

type VerifyDataOptions added in v0.3.0

type VerifyDataOptions struct {
	VerifyOptions
}

VerifyDataOptions defines options for the VerifyData method.

type VerifyOptions

type VerifyOptions struct {
	azkeys.VerifyOptions
}

VerifyOptions defines options for the Verify method.

type VerifyResult

type VerifyResult = alg.VerifyResult

VerifyResult contains information returned by the Verify method.

type WrapKeyAlgorithm added in v0.5.0

type WrapKeyAlgorithm = alg.WrapKeyAlgorithm

WrapKeyAlgorithm defines the key wrap algorithms supported by Azure Key Vault or Managed HSM.

const (
	// WrapKeyAlgorithmRSA15 uses RSA 1.5.
	WrapKeyAlgorithmRSA15 WrapKeyAlgorithm = azkeys.EncryptionAlgorithmRSA15

	// WrapKeyAlgorithmRSAOAEP uses RSA-OAEP.
	WrapKeyAlgorithmRSAOAEP WrapKeyAlgorithm = azkeys.EncryptionAlgorithmRSAOAEP

	// WrapKeyAlgorithmRSAOAEP256 uses RSA-OAEP-256.
	WrapKeyAlgorithmRSAOAEP256 WrapKeyAlgorithm = azkeys.EncryptionAlgorithmRSAOAEP256

	// WrapKeyAlgorithmA128KW uses A128-KW.
	WrapKeyAlgorithmA128KW WrapKeyAlgorithm = azkeys.EncryptionAlgorithmA128KW

	// WrapKeyAlgorithmA192KW uses A192-KW.
	WrapKeyAlgorithmA192KW WrapKeyAlgorithm = azkeys.EncryptionAlgorithmA192KW

	// WrapKeyAlgorithmA256KW uses A256-KW.
	WrapKeyAlgorithmA256KW WrapKeyAlgorithm = azkeys.EncryptionAlgorithmA256KW
)

type WrapKeyOptions added in v0.4.0

type WrapKeyOptions struct {
	azkeys.WrapKeyOptions
}

WrapKeyOptions defines options for the WrapKey method.

type WrapKeyResult added in v0.4.0

type WrapKeyResult = alg.WrapKeyResult

WrapKeyResult contains information returned by the WrapKey method.

Directories

Path Synopsis
Copied from https://github.com/Azure/azure-sdk-for-go/blob/1faa82f32a87a2e49bc5336beb1e4c14aa97c4b7/sdk/keyvault/internal/parse.go
Copied from https://github.com/Azure/azure-sdk-for-go/blob/1faa82f32a87a2e49bc5336beb1e4c14aa97c4b7/sdk/keyvault/internal/parse.go

Jump to

Keyboard shortcuts

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