philiprehberger-crypt 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b8b7e1b7ba025acb109315c7917651f67b9645ef6abc1f7699dbe4e471020b2
4
- data.tar.gz: 988b00641592540f69b355896dd6d524f7369830f93a33ad450909e4260671a2
3
+ metadata.gz: 789ed3adf81e8d52a357a47e485833197aa236ecfd9f66a941648e711bf40133
4
+ data.tar.gz: aa18d2c620b46d7a098843988684da63897b51d38373acdaaf8cafb594ced84b
5
5
  SHA512:
6
- metadata.gz: 85775a37db94d000bd73b20ed1d403e6dc5b891e38600860aea6ce0087c1c45d680886b3efc5212258b4f9132a691e7d52a92d1b2e824c935a698737f3590591
7
- data.tar.gz: 799433a04830123ffe629edaf5460dcad49f477e48108c66c7cbb1bbfb7c7611e78c9cf77f97cd7211de060b036d93eec7119e49cd7b1626f9af8a7aff47864e
6
+ metadata.gz: 8c6780048c0399326833092b4af23fb7dcd50162675e85eba91b279f7767f5693259f9a8aea780393fe60516a86e3835e6bc27b70098bd51765d24186f0bbb63
7
+ data.tar.gz: a744e5db314581c1d8f78a30487a1374a2cfe074c7cbc3b6294cb598fe65425b015eb425e4b3b9e745be618a6b8a3c9b1116acb4fd139e39d543b8592ab1da2a
data/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.5.0] - 2026-05-01
11
+
12
+ ### Added
13
+ - `Crypt.fingerprint(key)` — produces a short, stable identifier for a key (first 16 hex chars of `SHA-256(key)`). Stable across raw and hex key representations. Useful for log lines, key-id headers, and key rotation audits without leaking key material.
14
+
15
+ ## [0.4.0] - 2026-04-15
16
+
17
+ ### Added
18
+ - `hash_and_hmac(data, key:, algorithm:)` to compute both a hash and HMAC signature in a single call
19
+
10
20
  ## [0.3.0] - 2026-04-09
11
21
 
12
22
  ### Added
data/README.md CHANGED
@@ -106,6 +106,28 @@ Philiprehberger::Crypt.hmac_verify("payload", signature: signature, key: key)
106
106
  # => true
107
107
  ```
108
108
 
109
+ ### Combined Hash and HMAC
110
+
111
+ ```ruby
112
+ key = Philiprehberger::Crypt.random_hex(16)
113
+ result = Philiprehberger::Crypt.hash_and_hmac('payload', key: key)
114
+ # => { hash: '...', hmac: '...' }
115
+
116
+ result = Philiprehberger::Crypt.hash_and_hmac('payload', key: key, algorithm: :sha512)
117
+ ```
118
+
119
+ ### Key Fingerprint
120
+
121
+ Generate a short, safe identifier for a key — stable, hex-encoded, and never reveals the key itself.
122
+ Use it in log lines, key-id headers, and key rotation audits.
123
+
124
+ ```ruby
125
+ key = Philiprehberger::Crypt.random_hex(16)
126
+
127
+ Philiprehberger::Crypt.fingerprint(key) # => "a3f4b2c1d8e9f0a1"
128
+ # Same value for raw and hex representations of the same key
129
+ ```
130
+
109
131
  ### Secure Comparison
110
132
 
111
133
  ```ruby
@@ -130,7 +152,9 @@ Philiprehberger::Crypt.secure_compare(token_a, token_b)
130
152
  | `.random_hex(n)` | Generate a hex-encoded random string (2*n characters) |
131
153
  | `.random_bytes(n)` | Generate n cryptographically secure random bytes |
132
154
  | `.hash(data, algorithm:)` | Compute hex digest (SHA-256, SHA-384, or SHA-512) |
155
+ | `.hash_and_hmac(data, key:, algorithm:)` | Compute hash and HMAC signature in one call |
133
156
  | `.secure_compare(a, b)` | Constant-time string comparison |
157
+ | `.fingerprint(key)` | 16-char hex identifier (`SHA-256(key)[0,16]`) safe for logs and key-id headers |
134
158
  | `DecryptionError` | Raised when decryption fails |
135
159
 
136
160
  ## Development
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Philiprehberger
4
4
  module Crypt
5
- VERSION = '0.3.0'
5
+ VERSION = '0.5.0'
6
6
  end
7
7
  end
@@ -153,6 +153,22 @@ module Philiprehberger
153
153
  OpenSSL::Digest.new(algo).hexdigest(data.to_s)
154
154
  end
155
155
 
156
+ # Compute both a cryptographic hash and HMAC signature of data in one call.
157
+ #
158
+ # Delegates to {.hash} and {.hmac} using the same algorithm for both.
159
+ #
160
+ # @param data [String] the data to hash and sign
161
+ # @param key [String] the HMAC secret key
162
+ # @param algorithm [Symbol] hash algorithm (:sha256, :sha384, or :sha512)
163
+ # @return [Hash] with :hash (hex digest) and :hmac (hex HMAC signature)
164
+ # @raise [ArgumentError] if algorithm is unsupported
165
+ def self.hash_and_hmac(data, key:, algorithm: :sha256)
166
+ {
167
+ hash: hash(data, algorithm: algorithm),
168
+ hmac: hmac(data, key: key, algorithm: algorithm)
169
+ }
170
+ end
171
+
156
172
  # Re-encrypt data with a new key.
157
173
  #
158
174
  # @param encrypted [String] Base64-encoded encrypted data from {.encrypt}
@@ -213,6 +229,19 @@ module Philiprehberger
213
229
  OpenSSL.fixed_length_secure_compare(a, b)
214
230
  end
215
231
 
232
+ # Produce a short, stable identifier for a key without leaking key material.
233
+ #
234
+ # Returns the first 16 hex characters of `SHA-256(normalized_key)`. Stable
235
+ # across raw and hex representations of the same key. Useful for log lines
236
+ # ("encrypted with key #{Crypt.fingerprint(k)}"), key-id headers, and key
237
+ # rotation audits.
238
+ #
239
+ # @param key [String] a 32-byte raw or 64-character hex key
240
+ # @return [String] 16-character lowercase hex identifier
241
+ def self.fingerprint(key)
242
+ OpenSSL::Digest::SHA256.hexdigest(normalize_key(key))[0, 16]
243
+ end
244
+
216
245
  # @api private
217
246
  def self.normalize_key(key)
218
247
  return key if key.bytesize == KEY_LENGTH
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: philiprehberger-crypt
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Philip Rehberger
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-04-09 00:00:00.000000000 Z
11
+ date: 2026-05-01 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: A high-level encryption toolkit providing AES-256-GCM encryption and
14
14
  decryption, key rotation, envelope encryption, PBKDF2 key derivation, secure random