crypto

package
v1.8.5 Latest Latest
Warning

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

Go to latest
Published: Apr 17, 2026 License: Apache-2.0 Imports: 19 Imported by: 2

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AesCbcDecrypt deprecated

func AesCbcDecrypt(data string, passphrase string) (string, error)

AesCbcDecrypt will decrypt using aes cbc 256 bit, passphrase must be 32 bytes, if over 32 bytes, it be truncated.

Deprecated: AesCbcDecrypt strips ALL trailing NUL bytes (0x00) from the decrypted output via strings.ReplaceAll. This is how AesCbcEncrypt's NUL-padding is removed, but it also removes legitimate trailing NUL bytes that were part of the original plaintext — silent data corruption. CBC additionally lacks authentication, so a tampered or truncated ciphertext decrypts without error and returns attacker-influenced plaintext.

Use AesGcmDecrypt (paired with AesGcmEncrypt) instead. AES-GCM is AEAD: it returns an error on any ciphertext tampering and preserves arbitrary byte sequences (including embedded or trailing NULs) exactly.

AesCbcDecrypt remains fully supported for the v1.x release series per workspace rule #10 (observable-contract stability across minor versions). Scheduled for removal in v2.0.0. See _src/docs/repos/common/findings/remediation-report-2026-04-11-release-readiness.md P0-4 for the full hazard analysis.

func AesCbcEncrypt deprecated

func AesCbcEncrypt(data string, passphrase string) (string, error)

AesCbcEncrypt will encrypt using aes cbc 256 bit, passphrase must be 32 bytes, if over 32 bytes, it be truncated, encrypted data is represented in hex value.

Deprecated: AesCbcEncrypt uses NUL-byte padding (0x00) to align plaintext to the AES block size, and its paired AesCbcDecrypt strips ALL trailing NUL bytes from the decrypted output. This causes silent data corruption for any plaintext whose last byte is legitimately 0x00 — the trailing NUL is indistinguishable from padding and is removed on decrypt. CBC also lacks authentication, so a tampered ciphertext decrypts without error and returns attacker-influenced plaintext.

Use AesGcmEncrypt / AesGcmDecrypt instead. AES-GCM is an authenticated encryption mode (AEAD) that:

  • detects tampering via an authentication tag (decrypt returns an error on any bit flip),
  • requires no padding (so arbitrary byte sequences including embedded or trailing NUL bytes round-trip exactly), and
  • is the current default for symmetric bulk encryption per NIST SP 800-38D.

AesCbcEncrypt remains fully supported for the v1.x release series per workspace rule #10 (observable-contract stability across minor versions). Scheduled for removal in v2.0.0. See _src/docs/repos/common/findings/remediation-report-2026-04-11-release-readiness.md P0-4 for the full hazard analysis.

func AesCfbDecrypt deprecated

func AesCfbDecrypt(data string, passphrase string) (string, error)

Deprecated: AesCfbDecrypt uses CFB mode which is an unauthenticated stream cipher. See AesCfbEncrypt for details. Use AesGcmDecrypt instead.

AesCfbDecrypt will decrypt using aes cfb 256 bit, passphrase must be 32 bytes, if over 32 bytes, it be truncated.

IMPORTANT: passphrase MUST be a high-entropy 32-byte key, NOT a password.

func AesCfbEncrypt deprecated

func AesCfbEncrypt(data string, passphrase string) (string, error)

Deprecated: AesCfbEncrypt uses CFB mode which is an unauthenticated stream cipher. An attacker who can modify ciphertext can produce controlled plaintext changes (bit-flipping attack) without detection. Use AesGcmEncrypt instead, which provides both confidentiality and authentication (AEAD). The CFB functions remain callable through the entire v1.x series per workspace rule #10; removal is scheduled for v2.0.0.

AesCfbEncrypt will encrypt using aes cfb 256 bit, passphrase must be 32 bytes, if over 32 bytes, it be truncated, encrypted data is represented in hex value.

IMPORTANT: passphrase MUST be a high-entropy 32-byte key, NOT a password.

func AesGcmDecrypt

func AesGcmDecrypt(data string, passphrase string) (string, error)

AesGcmDecrypt will decrypt using aes gcm 256 bit, passphrase must be 32 bytes, if over 32 bytes, it be truncated.

IMPORTANT: passphrase MUST be a high-entropy 32-byte key (e.g., output of a cryptographic random generator), NOT a human-memorizable password. For password-based encryption, derive the key via scrypt or argon2id first. This function uses raw byte-slice truncation, not a key derivation function.

func AesGcmEncrypt

func AesGcmEncrypt(data string, passphrase string) (string, error)

AesGcmEncrypt will encrypt using aes gcm 256 bit, passphrase must be 32 bytes, if over 32 bytes, it be truncated, encrypted data is represented in hex value.

IMPORTANT: passphrase MUST be a high-entropy 32-byte key (e.g., output of a cryptographic random generator), NOT a human-memorizable password. For password-based encryption, derive the key via scrypt or argon2id first. This function uses raw byte-slice truncation, not a key derivation function.

func AppendHmac

func AppendHmac(encryptedData string, key string) (string, error)

AppendHmac will calculate the hmac for the given encrypted data based on the given key, and append the Hmac to the end of the encrypted data and return the newly assembled encrypted data with hmac.

IMPORTANT: key MUST be a high-entropy 32-byte key (e.g., the AES key used to encrypt the data), NOT a human-memorizable password. This function uses raw byte-slice truncation, not a key derivation function.

func FnvHashDigit added in v1.3.1

func FnvHashDigit(data string, digitLimit int) int

FnvHashDigit returns persistent hash digit value, limited by the digit limit parameter

func Generate32ByteRandomKey

func Generate32ByteRandomKey(passphrase string) (string, error)

Generate32ByteRandomKey will generate a random 32 byte key based on passphrase and random salt, passphrase does not need to be any specific length

func Md5 deprecated

func Md5(data string, salt string) string

Md5 hashes the given data+salt with the MD5 algorithm and returns the uppercase hex digest.

Deprecated: MD5 is cryptographically broken. It is vulnerable to collision attacks (Wang & Yu, 2005; chosen-prefix attacks since 2008) and must NOT be used for:

  • password hashing (use PasswordHash, which wraps bcrypt)
  • digital signatures or any integrity check where an attacker may influence the input (use Sha256 or [Sha512])
  • security tokens, session IDs, or anything that must be unforgeable (use Sha256 / [Sha512] with a keyed HMAC, or a CSPRNG)

The only remaining safe use is non-security checksums (e.g., a cache key that protects against accidental corruption, not malicious input). If you need a non-cryptographic hash for that purpose, prefer a dedicated one such as xxhash or fnv.

This function remains callable in v1.x for backward compatibility and will be removed in v2.0.0. Consumers are expected to migrate to Sha256 or [Sha512] before the v2.0.0 cut. See CHANGELOG.md and the "Compatibility and Stability" section of README.md for the migration policy.

func PasswordHash

func PasswordHash(password string, cost int) (string, error)

PasswordHash uses BCrypt to hash the given password and return a corresponding hash, suggested cost = 13 (440ms), if cost is left as 0, then default 13 is assumed

func PasswordVerify

func PasswordVerify(password string, hash string) (bool, error)

PasswordVerify uses BCrypt to verify the input password against a prior hash version to see if match

func RsaAesParseTPKHashFromEncryptedPayload

func RsaAesParseTPKHashFromEncryptedPayload(encryptedData string) string

RsaAesParseTPKHashFromEncryptedPayload will get the public key TPK hash from the embedded encrypted data string

func RsaAesPrivateKeyDecryptAndVerify deprecated

func RsaAesPrivateKeyDecryptAndVerify(encryptedData string, recipientPrivateKeyHexOrPem string) (plainText string, senderPublicKeyHexOrPem string, err error)

RsaAesPrivateKeyDecryptAndVerify is a simplified wrapper method to decrypt incoming encrypted payload envelop that was previously encrypted using the RsaAesPublicKeyEncryptAndSign(), this function will use recipient's private key to decrypt the rsa encrypted dynamic aes key and then using the dynamic aes key to decrypt the aes encrypted data payload, this function will then parse the decrypted payload and perform a verification of signature using the sender's public key

usage tip: the sender's public key can then be used to encrypt the return data back to the sender as a reply using RsaAesPublicKeyEncryptedAndSign(),

in this usage pattern, only the public key is used in each messaging cycle, while the aes key is dynamically generated each time and no prior knowledge of it is known,
since the public key encrypted data cannot be decrypted unless with private key, then as long as the private key is protected, then the messaging pipeline will be secured,
furthermore, by using sender private key sign and sender public key verify into the message authentication, we further ensure the plain text data is coming from the expected source

recipientPrivateKeyHexOrPem = can be either HEX or PEM

Deprecated: this function is the decrypt counterpart of the deprecated RsaAesPublicKeyEncryptAndSign and shares its two hazards:

  1. It trusts the trailing 64-char TPK hash as a routing identifier but performs NO envelope-level keyed integrity check before handing the AES-GCM ciphertext to the decrypter. GCM itself authenticates the inner plaintext, but a tampered rsaEncryptedAesKey (or a tampered concatenation of the two) is not detected until GCM decryption fails — and even then, an attacker who can re-wrap a chosen AES key under the recipient's public key can substitute the entire payload at the price of only the GCM tag.
  2. It parses the decrypted inner plaintext with strings.Split on 0x0B (VT), so any envelope whose original plaintext contained a VT byte decodes into the wrong number of parts and fails with a confusing "Expected 3 Parts Exactly" error instead of returning the caller's data.

Use RsaAesPrivateKeyDecryptAndVerifyHmac instead. It verifies an HMAC-SHA256 tag over rsaEncryptedAesKey || aesGcmEncryptedBody BEFORE invoking the GCM decrypter (fail-fast on tampering), and parses the inner plaintext with length-prefixed fields so arbitrary byte sequences round-trip exactly.

This function remains fully callable through the entire v1.x release series per workspace rule #10 (observable-contract stability). Removal is scheduled for v2.0.0. See _src/docs/repos/common/findings/remediation-report-2026-04-11-release-readiness.md P0-5 for the full hazard analysis.

func RsaAesPrivateKeyDecryptAndVerifyHmac added in v1.7.9

func RsaAesPrivateKeyDecryptAndVerifyHmac(encryptedData string, recipientPrivateKeyHexOrPem string) (plainText string, senderPublicKeyHexOrPem string, err error)

RsaAesPrivateKeyDecryptAndVerifyHmac is the v1.7.9 additive replacement for the deprecated RsaAesPrivateKeyDecryptAndVerify. It decrypts envelopes produced by RsaAesPublicKeyEncryptAndSignHmac.

Verification order (fail-fast on tampering):

  1. Strip STX/ETX.
  2. Check the literal "V2" format marker. A V1 payload has its first byte equal to a hex char of the RSA-wrapped AES key, not 'V', so it is rejected here with a clear error instead of partially parsing and failing later.
  3. Split the body into rsaEncryptedAesKey (512 hex chars) || aesGcmEncryptedBody (variable) || hmacTag (64 hex chars).
  4. RSA-decrypt rsaEncryptedAesKey with recipient's private key to recover the per-envelope AES key.
  5. Recompute HMAC-SHA256(aesKey, rsaEncryptedAesKey || aesGcmEncryptedBody) and compare against hmacTag in constant time. REJECT if they do not match — do NOT invoke AES-GCM decrypt on a tampered envelope.
  6. AES-GCM decrypt aesGcmEncryptedBody with aesKey.
  7. Parse the decrypted inner plaintext as three length-prefixed fields (plainText, senderPublicKeyHexOrPem, signature).
  8. RSA-verify signature against plainText using senderPublicKeyHexOrPem.

Only after all eight steps pass does the function return the plainText and senderPublicKeyHexOrPem to the caller.

recipientPrivateKeyHexOrPem = may be HEX or PEM.

func RsaAesPublicKeyEncryptAndSign deprecated

func RsaAesPublicKeyEncryptAndSign(plainText string, recipientPublicKeyHexOrPem string, senderPublicKeyHexOrPem string, senderPrivateKeyHexOrPem string) (encryptedData string, err error)

RsaAesPublicKeyEncryptAndSign is a simplified wrapper method to generate a random AES key, then encrypt plainText using AES GCM, and then sign plain text data using sender's private key, and then using recipient's public key to encrypt the dynamic aes key, and finally compose the encrypted payload that encapsulates a full envelop:

<STX>RsaPublicKeyEncryptedAESKeyData + AesGcmEncryptedPayload(PlainTextData<VT>SenderPublicKey<VT>PlainTextDataSignature)<ETX>

warning: VT is used in encrypted payload as separator, make sure to escape VT if it is to be used inside the plainTextData <<< IMPORTANT

recipientPublicKeyHexOrPem = can be either HEX or PEM senderPublicKeyHexOrPem = can be either HEX or PEM senderPrivateKeyHexOrPem = can be either HEX or PEM

Deprecated: this function uses two brittle constructions that its replacement avoids:

  1. The trailing 64-char hex value appended to the envelope is Sha256(recipientPublicKey, "TPK@2019") — a public, unkeyed hash that any attacker can recompute. It is used only as a recipient-key lookup identifier (see RsaAesParseTPKHashFromEncryptedPayload), but its presence alongside the ciphertext invites readers to mistake it for an integrity tag. There is no envelope-level keyed integrity binding the RSA-wrapped AES key to the AES-GCM ciphertext.
  2. The AES-GCM plaintext is the 0x0B (VT) delimited triple plainText<VT>senderPublicKey<VT>signature. If the caller's plainText itself contains a VT byte, the decrypt-side parser (strings.Split) splits incorrectly and the envelope is unrecoverable — a silent footgun that the godoc warns about but is easy to trip on.

Use RsaAesPublicKeyEncryptAndSignHmac instead. It keeps the same RSA-OAEP-SHA256 key wrapping + AES-GCM payload encryption, but:

  • replaces the VT-delimited triple with length-prefixed fields so arbitrary byte sequences (including embedded VT / NUL / control bytes) round-trip exactly, and
  • appends a real HMAC-SHA256 tag keyed by the per-envelope AES key over the entire RSA-wrapped-key || AES-GCM-ciphertext body, with a 2-byte "V2" format marker so V1 and V2 payloads are unambiguously distinguishable at decrypt time.

This function remains fully callable through the entire v1.x release series per workspace rule #10 (observable-contract stability). Removal is scheduled for v2.0.0. See _src/docs/repos/common/findings/remediation-report-2026-04-11-release-readiness.md P0-5 for the full hazard analysis.

func RsaAesPublicKeyEncryptAndSignHmac added in v1.7.9

func RsaAesPublicKeyEncryptAndSignHmac(plainText string, recipientPublicKeyHexOrPem string, senderPublicKeyHexOrPem string, senderPrivateKeyHexOrPem string) (encryptedData string, err error)

RsaAesPublicKeyEncryptAndSignHmac is the v1.7.9 additive replacement for the deprecated RsaAesPublicKeyEncryptAndSign. It preserves the same security goals (hybrid RSA-wrapped AES key + AES-GCM body + sender signature verified by the recipient) but fixes two V1 hazards:

  1. V1's trailing 64-char value is an unkeyed hash that can be recomputed by any attacker and provides no integrity. V2 appends an HMAC-SHA256 tag keyed by the per-envelope AES key, binding rsaEncryptedAesKey and aesGcmEncryptedBody together so tampering of either is detected before GCM decrypt is attempted.
  2. V1's inner plaintext is the 0x0B-delimited triple plainText<VT>senderPublicKey<VT>signature. If plainText contains a VT byte, the decrypt-side parser splits incorrectly and the envelope is unrecoverable. V2 uses length-prefixed fields so arbitrary byte sequences (VT, NUL, any control byte, binary data) round-trip exactly.

recipientPublicKeyHexOrPem, senderPublicKeyHexOrPem, senderPrivateKeyHexOrPem = may each be HEX or PEM. Same as V1.

Returns an envelope starting with STX, the literal "V2" format marker, the hex-encoded RSA-wrapped AES key, the hex-encoded AES-GCM ciphertext, the 64-char HMAC-SHA256 tag, and a trailing ETX. The envelope can be safely transported as a single printable string (hex-only body plus two ASCII control framing bytes).

func RsaCreateKey

func RsaCreateKey() (privateKey string, publicKey string, err error)

RsaCreateKey generates the private and public key pair, expressed in hex code value

func RsaPrivateKeyDecrypt

func RsaPrivateKeyDecrypt(data string, privateKeyHexOrPem string) (string, error)

RsaPrivateKeyDecrypt will decrypt rsa public key encrypted data using its corresponding rsa private key

privateKeyHexOrPem = can be either HEX or PEM

func RsaPrivateKeyDecryptAndPublicKeyVerify

func RsaPrivateKeyDecryptAndPublicKeyVerify(data string, recipientPrivateKeyHexOrPem string, signatureHex string, senderPublicKeyHexOrPem string) (plaintext string, verified bool, err error)

RsaPrivateKeyDecryptAndPublicKeyVerify will decrypt given data using recipient's rsa private key, and then using sender's rsa public key to verify if the signature given is a match, NOTE: data represents the encrypted data

recipientPrivateKeyHexOrPem = can be either HEX or PEM senderPublicKeyHexOrPem = can be either HEX or PEM

func RsaPrivateKeySign

func RsaPrivateKeySign(data string, privateKeyHexOrPem string) (string, error)

RsaPrivateKeySign will sign the plaintext data using the given private key, NOTE: data must be plain text before encryption as signature verification is against plain text data signature is returned via hex

privateKeyHexOrPem = can be either HEX or PEM

func RsaPublicKeyEncrypt

func RsaPublicKeyEncrypt(data string, publicKeyHexOrPem string) (string, error)

RsaPublicKeyEncrypt will encrypt given data using rsa public key, encrypted data is represented in hex value

publicKeyHexOrPem = can be either HEX or PEM

func RsaPublicKeyEncryptAndPrivateKeySign

func RsaPublicKeyEncryptAndPrivateKeySign(data string, recipientPublicKeyHexOrPem string, senderPrivateKeyHexOrPem string) (encryptedData string, signature string, err error)

RsaPublicKeyEncryptAndPrivateKeySign will encrypt given data using recipient's rsa public key, and then using sender's rsa private key to sign, NOTE: data represents the plaintext data, encrypted data and signature are represented in hex values

recipientPublicKeyHexOrPem = can be either HEX or PEM senderPrivateKeyHexOrPem = can be either HEX or PEM

func RsaPublicKeyVerify

func RsaPublicKeyVerify(data string, publicKeyHexOrPem string, signatureHex string) error

RsaPublicKeyVerify will verify the plaintext data using the given public key, NOTE: data must be plain text before encryption as signature verification is against plain text data if verification is successful, nil is returned, otherwise error is returned

publicKeyHexOrPem = can be either HEX or PEM

func Sha256

func Sha256(data string, salt string) string

Sha256 hashing (always 64 bytes output)

func ValidateHmac

func ValidateHmac(encryptedDataWithHmac string, key string) (string, error)

ValidateHmac will verify if the appended hmac validates against the message based on the given key, and parse the hmac out and return the actual message if hmac validation succeeds, if hmac validation fails, then blank is returned and the error contains the failure reason.

IMPORTANT: key MUST be a high-entropy 32-byte key (e.g., the AES key used to encrypt the data), NOT a human-memorizable password. This function uses raw byte-slice truncation, not a key derivation function.

Types

This section is empty.

Jump to

Keyboard shortcuts

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