philiprehberger-crypt

Tests Gem Version Last updated

High-level encryption with AES-256-GCM, key derivation, and secure random

Requirements

  • Ruby >= 3.1

Installation

Add to your Gemfile:

gem "philiprehberger-crypt"

Or install directly:

gem install philiprehberger-crypt

Usage

require "philiprehberger/crypt"

# Generate a random key and encrypt data
key = Philiprehberger::Crypt.random_hex(16)
encrypted = Philiprehberger::Crypt.encrypt("Hello, World!", key: key)
decrypted = Philiprehberger::Crypt.decrypt(encrypted, key: key)
# => "Hello, World!"

Key Derivation

salt = Philiprehberger::Crypt.random_salt
key = Philiprehberger::Crypt.derive_key("my-password", salt: salt)

encrypted = Philiprehberger::Crypt.encrypt("secret data", key: key)
decrypted = Philiprehberger::Crypt.decrypt(encrypted, key: key)

Secure Random Generation

Philiprehberger::Crypt.random_salt    # => 32-byte random salt
Philiprehberger::Crypt.random_token   # => URL-safe Base64 token
Philiprehberger::Crypt.random_hex(16) # => 32-character hex string

Key Rotation

old_key = Philiprehberger::Crypt.random_hex(16)
new_key = Philiprehberger::Crypt.random_hex(16)

encrypted = Philiprehberger::Crypt.encrypt("secret", key: old_key)
rotated = Philiprehberger::Crypt.rotate_key(encrypted, old_key: old_key, new_key: new_key)

Philiprehberger::Crypt.decrypt(rotated, key: new_key)
# => "secret"

Envelope Encryption

master_key = Philiprehberger::Crypt.random_hex(16)

envelope = Philiprehberger::Crypt.envelope_encrypt("secret data", master_key: master_key)
# => { encrypted_data: "...", encrypted_key: "..." }

Philiprehberger::Crypt.envelope_decrypt(envelope, master_key: master_key)
# => "secret data"

Hashing

Philiprehberger::Crypt.hash("data to hash")
# => "b8e6cd431..."  (SHA-256 hex digest)

Philiprehberger::Crypt.hash("data", algorithm: :sha384)
Philiprehberger::Crypt.hash("data", algorithm: :sha512)

Random Bytes

Philiprehberger::Crypt.random_bytes(32)
# => 32-byte binary string

HMAC Signing

key = Philiprehberger::Crypt.random_hex(16)
signature = Philiprehberger::Crypt.hmac("payload", key: key)

Philiprehberger::Crypt.hmac_verify("payload", signature: signature, key: key)
# => true

Combined Hash and HMAC

key = Philiprehberger::Crypt.random_hex(16)
result = Philiprehberger::Crypt.hash_and_hmac('payload', key: key)
# => { hash: '...', hmac: '...' }

result = Philiprehberger::Crypt.hash_and_hmac('payload', key: key, algorithm: :sha512)

Secure Comparison

Philiprehberger::Crypt.secure_compare(token_a, token_b)
# => true/false (constant-time comparison)

API

Method Description
.encrypt(data, key:) Encrypt data using AES-256-GCM
.decrypt(data, key:) Decrypt data encrypted with .encrypt
.rotate_key(encrypted, old_key:, new_key:) Re-encrypt data with a new key
.envelope_encrypt(data, master_key:) Envelope encrypt with random data key
.envelope_decrypt(envelope, master_key:) Decrypt envelope-encrypted data
.derive_key(password, salt:, iterations:) Derive a 32-byte key using PBKDF2-HMAC-SHA256
.hmac(data, key:, algorithm:) Compute hex-encoded HMAC signature
.hmac_verify(data, signature:, key:, algorithm:) Constant-time HMAC verification
.random_salt Generate a 32-byte cryptographic random salt
.random_token Generate a URL-safe Base64 random token
.random_hex(n) Generate a hex-encoded random string (2*n characters)
.random_bytes(n) Generate n cryptographically secure random bytes
.hash(data, algorithm:) Compute hex digest (SHA-256, SHA-384, or SHA-512)
.hash_and_hmac(data, key:, algorithm:) Compute hash and HMAC signature in one call
.secure_compare(a, b) Constant-time string comparison
DecryptionError Raised when decryption fails

Development

bundle install
bundle exec rspec
bundle exec rubocop

Support

If you find this project useful:

Star the repo

🐛 Report issues

💡 Suggest features

❤️ Sponsor development

🌐 All Open Source Projects

💻 GitHub Profile

🔗 LinkedIn Profile

License

MIT