libcipher

package
v0.0.76 Latest Latest
Warning

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

Go to latest
Published: Sep 25, 2025 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package libcipher provides a collection of cryptographic utilities for encryption, decryption, integrity verification, and secure key generation. It includes implementations for AES-GCM (authenticated encryption) and AES-CBC combined with HMAC (for encryption with integrity verification), as well as functions for sealed HMAC hash creation and constant-time comparison.

The package offers the following functionalities:

  • AES-GCM based encryption/decryption, which provides both confidentiality and authenticity.
  • AES-CBC with HMAC for scenarios where nonce collisions are a concern, especially in high-volume or distributed environments. This mode encrypts data using AES-CBC (with PKCS#7 padding) and ensures integrity via an HMAC over the encrypted payload and additional data.
  • Sealed HMAC hash creation and comparison, where a unique salt is automatically added and the resulting JSON-encoded object encapsulates both the computed HMAC digest and the salt.
  • Cryptographically secure key generation.

Security Considerations:

  • The encryption key and integrity key must be kept secret and must be distinct. Reusing keys for different purposes can compromise security.
  • When using AES-CBC with HMAC, ensure that the entire ciphertext fits in memory as the HMAC is computed over the complete message. For high-volume systems, AES-GCM may be preferred.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CheckHash

func CheckHash(signingKey string, salt string, shouldBe string, hash []byte) (bool, error)

CheckHash verifies the shouldBe string against the hash. params: - signingKey (string) - the signing key for the hash - salt (string) - the salt used for the hash - password (string) - the password to verify - hash ([]byte) - the stored hash to compare against returns: (bool, error) - whether the password matches the hash and an error if any

Note: Think twice, maybe bycrypt is what you need.

func Equal

func Equal(sealedHash1, sealedHash2 []byte) bool

Equal compares two JSON-encoded sealed hashes in constant time. It unmarshals each sealed hash into a SealedHash struct and then compares both the Hash and Salt fields using hmac.Equal.

Usage:

ok := Equal(sealedHash1, sealedHash2)
if !ok {
    // the sealed hashes do not match
}

Returns true if both the hash and salt components are equal; otherwise, false. If either sealed hash cannot be unmarshalled, the function returns false.

func GenerateKey

func GenerateKey(keyLength int) (string, error)

GenerateKey generates a cryptographically random key with the specified length.

func NewHash

func NewHash(args GenerateHashArgs, hashfn func() hash.Hash) ([]byte, error)

NewHash generates a sealed hash from the provided arguments and hash function. It computes an HMAC digest over the concatenation of the input data and a unique salt, and packages the result along with the salt in a JSON-encoded SealedHash object.

Usage:

sealed, err := NewHash(GenerateHashArgs{
    Hash:       data,
    SigningKey: key,
}, sha256.New)
if err != nil {
    // handle error
}

When to use: Use NewHash when you need to securely generate a hash that verifies the integrity and authenticity of data. A unique salt is automatically added so that identical inputs produce distinct outputs, and the signing key is applied during the HMAC computation. The signing key is not required during verification since it is already embedded in the computed HMAC digest.

Types

type CipherTextError

type CipherTextError string

func (CipherTextError) Error

func (e CipherTextError) Error() string

type Decryptor

type Decryptor interface {
	// Encrypts/Decrypts a message, misuse may lead to a panic.
	Crypt(cipherpackage []byte) ([]byte, []byte, error)
}

provides a method to crypt a cipher package. Misuse of this method may lead to a panic.

func NewCBCHMACDecryptor

func NewCBCHMACDecryptor(encryptionKey []byte, integrityKey []byte, calculateMAC func() hash.Hash) (Decryptor, error)

Configure & init the AES-CBC+HMAC cryptor in decryption mode.

func NewGCMDecryptor

func NewGCMDecryptor(encryptionKey []byte) (Decryptor, error)

NewGCMDecryptor creates a new Decryptor using AES-GCM with the given key.

type EncryptionKeyError

type EncryptionKeyError string

func (EncryptionKeyError) Error

func (e EncryptionKeyError) Error() string

type Encryptor

type Encryptor interface {
	// Encrypts/Decrypts a message, misuse may lead to a panic.
	Crypt(message []byte, additionalData []byte) ([]byte, error)
}

provides a method to crypt a message with additional data. Misuse of this method may lead to a panic.

func NewCBCHMACEncryptor

func NewCBCHMACEncryptor(encryptionKey []byte, integrityKey []byte, calculateMAC func() hash.Hash, rand io.Reader) (Encryptor, error)

Configure & init the AES-CBC+HMAC cryptor in encryption mode. AES-CBC with PKCS7 padding HMAC for integrity.

The final encrypted string format:
[ MAC | AD-Length | AD | Initialization Vector | Block 1 | Block 2 | ... ]
uses rand from the arguments for introducing randomness.

Don't use this for big messages, the whole cypher has to be in mem for computing the Hmac.

The encryption key and integrity key must be distinct. Both keys have to be kept secret. Rotating must be done to both keys simultaneously.

Compromised Encryption Key:

An attacker, possessing the encryption key, could decrypt sensitive data.
If you rotate only the integrity key, they still have access to the previously encrypted data.

Compromised Integrity Key:

An attacker with the integrity key could potentially modify encrypted data,
forge HMACs, and tamper with the system without detection.
Even if you rotate the encryption key, the integrity of past data is compromised.

the MAC is calculated from ( AD-Length | AD | Initialization Vector | Block 1 | Block 2 | ... )

GCM Comparison:

	Use CBC with HMAC over GCM (or any stream cipher) when avoiding nonce collisions can be challenging is a problem.
	This is the case if you deal with:
	- high-volume systems (the probability of nonce collisions increases, especially if the nonce space is limited).
	- distributed environments (coordinating nonce generation across nodes and ensuring uniqueness becomes even more complex).
	- or scenarios where encrypted data needs to be stored persistently. For example, if encrypted data is stored in a database.
      and later retrieved and re-encrypted, ensuring that a new, unique nonce is used each time can be challenging.

Since this is a one-person project, ensure you review the code before using it to validate its security and correctness.

func NewGCMEncryptor

func NewGCMEncryptor(encryptionKey []byte, rand io.Reader) (Encryptor, error)

NewGCMEncryptor creates a new Encryptor using AES-GCM with the given key.

type GenerateHashArgs

type GenerateHashArgs struct {
	Payload    []byte
	SigningKey []byte
	Salt       []byte
}

GenerateHashArgs contains the input parameters for generating a sealed hash. The Payload field is the data to be hashed, and SigningKey is the key used to compute the HMAC digest. The SigningKey should be kept secret.

type HashError

type HashError string

HashError represents an error during hash generation.

func (HashError) Error

func (e HashError) Error() string

type IntegrityKeyError

type IntegrityKeyError string

func (IntegrityKeyError) Error

func (e IntegrityKeyError) Error() string

type InvalidUsageError

type InvalidUsageError string

func (InvalidUsageError) Error

func (e InvalidUsageError) Error() string

type KeyGenerationError

type KeyGenerationError string

func (KeyGenerationError) Error

func (e KeyGenerationError) Error() string

type MessageError

type MessageError string

func (MessageError) Error

func (e MessageError) Error() string

Jump to

Keyboard shortcuts

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