Documentation ¶
Overview ¶
Package pbkdf2 contains a key provider that takes a passphrase and emits a PBKDF2 hash of the configured length.
Example (Decrypt) ¶
This example is a bare-bones configuration for a static key provider. It is mainly intended to demonstrate how you can use parse configuration and construct a static key provider from it.
package main import ( "fmt" "github.com/adrien-f/opentofu-opened/pkg/encryption/keyprovider/pbkdf2" "github.com/hashicorp/hcl/v2/gohcl" "github.com/adrien-f/opentofu-opened/pkg/encryption/config" ) var configuration = `key_provider "pbkdf2" "foo" { passphrase = "correct-horse-battery-staple" } ` // This example is a bare-bones configuration for a static key provider. // It is mainly intended to demonstrate how you can use parse configuration // and construct a static key provider from it. func main() { configStruct := pbkdf2.New().ConfigStruct() // Parse the config: parsedConfig, diags := config.LoadConfigFromString("config.hcl", configuration) if diags.HasErrors() { panic(diags) } // Use gohcl to parse the hcl block from parsedConfig into the static configuration struct: if err := gohcl.DecodeBody( parsedConfig.KeyProviderConfigs[0].Body, nil, configStruct, ); err != nil { panic(err) } // Create the actual key provider. keyProvider, keyMeta, err := configStruct.Build() if err != nil { panic(err) } // Fill in the metadata stored with the encrypted form: meta := keyMeta.(*pbkdf2.Metadata) meta.Salt = []byte{0x10, 0xec, 0x3d, 0x3f, 0xe0, 0x2a, 0xd2, 0xbe, 0xe6, 0xf1, 0xf5, 0x54, 0xf, 0x8e, 0x6b, 0xbe, 0x3b, 0x8b, 0x29, 0x44, 0x5c, 0xf5, 0x2, 0xd2, 0x7d, 0x47, 0xad, 0x55, 0x4a, 0xa8, 0x97, 0x1f} meta.Iterations = 600000 meta.HashFunction = "sha512" meta.KeyLength = 32 // Get decryption key from the provider. keys, _, err := keyProvider.Provide(meta) if err != nil { panic(err) } fmt.Printf("%x", keys.DecryptionKey) }
Output: 225872367198760137e0a18580433447bbf578fbe2b87ff36aef3c175fe5709c
Index ¶
- Constants
- type Config
- func (c *Config) Build() (keyprovider.KeyProvider, keyprovider.KeyMeta, error)
- func (c *Config) WithHashFunction(hashFunction HashFunctionName) *Config
- func (c *Config) WithIterations(iterations int) *Config
- func (c *Config) WithKeyLength(length int) *Config
- func (c *Config) WithPassphrase(passphrase string) *Config
- func (c *Config) WithSaltLength(length int) *Config
- type Descriptor
- type HashFunction
- type HashFunctionName
- type Metadata
Examples ¶
Constants ¶
const ( MinimumIterations int = 200000 MinimumPassphraseLength int = 16 )
const ( // DefaultSaltLength specifies the default salt length in bytes. DefaultSaltLength int = 32 // DefaultIterations contains the default iterations to use. The number is set to the current recommendations // outlined here: // https://cheatsheetseries.owasp.org/cheatsheets/Password_Storage_Cheat_Sheet.html#pbkdf2 DefaultIterations int = 600000 // DefaultKeyLength is the default output length. We set it to the key length required by AES-GCM 256 DefaultKeyLength int = 32 )
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { Passphrase string `hcl:"passphrase"` KeyLength int `hcl:"key_length,optional"` Iterations int `hcl:"iterations,optional"` HashFunction HashFunctionName `hcl:"hash_function,optional"` SaltLength int `hcl:"salt_length,optional"` // contains filtered or unexported fields }
func (*Config) Build ¶
func (c *Config) Build() (keyprovider.KeyProvider, keyprovider.KeyMeta, error)
func (*Config) WithHashFunction ¶
func (c *Config) WithHashFunction(hashFunction HashFunctionName) *Config
WithHashFunction sets the hash function and returns the same config for chaining
func (*Config) WithIterations ¶
WithIterations sets the iterations and returns the same config for chaining
func (*Config) WithKeyLength ¶
WithKeyLength sets the key length and returns the same config for chaining
func (*Config) WithPassphrase ¶
WithPassphrase adds the passphrase and returns the same config for chaining.
func (*Config) WithSaltLength ¶
WithSaltLength sets the salt length and returns the same config for chaining
type Descriptor ¶
type Descriptor interface { keyprovider.Descriptor TypedConfig() *Config }
Descriptor provides TypedConfig on top of keyprovider.Descriptor.
type HashFunctionName ¶
type HashFunctionName string
HashFunctionName describes a hash function to use for PBKDF2 hash generation. While you could theoretically supply your own from outside the package, please don't do that. Include your hash function in this package. (Thanks Go for the lack of visibility constraints.)
const ( SHA256HashFunctionName HashFunctionName = "sha256" SHA512HashFunctionName HashFunctionName = "sha512" DefaultHashFunctionName HashFunctionName = SHA512HashFunctionName )
func (HashFunctionName) Function ¶
func (h HashFunctionName) Function() HashFunction
Function returns the underlying hash function for the name.
func (HashFunctionName) Validate ¶
func (h HashFunctionName) Validate() error
Validate checks if the specified hash function name is valid.
type Metadata ¶
type Metadata struct { Salt []byte `json:"salt"` Iterations int `json:"iterations"` HashFunction HashFunctionName `json:"hash_function"` KeyLength int `json:"key_length"` }
Metadata describes the metadata to be stored alongside the encrypted form.
Example ¶
package main import ( "bytes" "fmt" "github.com/adrien-f/opentofu-opened/pkg/encryption/config" "github.com/adrien-f/opentofu-opened/pkg/encryption/keyprovider/pbkdf2" "github.com/hashicorp/hcl/v2/gohcl" ) var metadataExampleConfiguration = `key_provider "pbkdf2" "foo" { passphrase = "correct-horse-battery-staple" } ` func main() { configStruct := pbkdf2.New().ConfigStruct() // Parse the config: parsedConfig, diags := config.LoadConfigFromString("config.hcl", metadataExampleConfiguration) if diags.HasErrors() { panic(diags) } // Use gohcl to parse the hcl block from parsedConfig into the static configuration struct: if err := gohcl.DecodeBody( parsedConfig.KeyProviderConfigs[0].Body, nil, configStruct, ); err != nil { panic(err) } // Create the actual key provider. keyProvider, keyMeta, err := configStruct.Build() if err != nil { panic(err) } // The first time around, let's get an encryption key: oldKeys, oldMeta, err := keyProvider.Provide(keyMeta) if err != nil { panic(err) } // The second time, you can pass in the metadata from the previous encryption: newKeys, _, err := keyProvider.Provide(oldMeta) if err != nil { panic(err) } // The old encryption and new decryption key will be the same: if bytes.Equal(oldKeys.EncryptionKey, newKeys.DecryptionKey) { fmt.Println("The keys match!") } }
Output: The keys match!