3737public interface KMSProvider extends Configurable , Adapter {
3838
3939 /**
40- * Get the unique name of this provider
40+ * Returns {@code true} if the given HSM profile configuration key name refers
41+ * to a
42+ * sensitive value (PIN, password, secret, or private key) that must be
43+ * encrypted at
44+ * rest and masked in API responses.
4145 *
42- * @return provider name (e.g., "database", "pkcs11")
46+ * <p>
47+ * This is a shared naming-convention helper used by both KMS providers (when
48+ * loading/storing profile details) and the KMS manager (when building API
49+ * responses).
50+ *
51+ * @param key configuration key name (case-insensitive); null returns false
52+ * @return true if the key is considered sensitive
4353 */
44- String getProviderName ();
54+ static boolean isSensitiveKey (String key ) {
55+ if (key == null ) {
56+ return false ;
57+ }
58+ return key .equalsIgnoreCase ("pin" ) ||
59+ key .equalsIgnoreCase ("password" ) ||
60+ key .toLowerCase ().contains ("secret" ) ||
61+ key .equalsIgnoreCase ("private_key" );
62+ }
4563
4664 /**
47- * Create a new Key Encryption Key (KEK) in the secure backend with explicit HSM profile.
65+ * Get the unique name of this provider
4866 *
49- * @param purpose the purpose/scope for this KEK
50- * @param label human-readable label for the KEK (must be unique within purpose)
51- * @param keyBits key size in bits (typically 128, 192, or 256)
52- * @param hsmProfileId optional HSM profile ID to create the KEK in (null for auto-resolution/default)
53- * @return the KEK identifier (label or handle) for later reference
54- * @throws KMSException if KEK creation fails
67+ * @return provider name (e.g., "database", "pkcs11")
5568 */
56- String createKek ( KeyPurpose purpose , String label , int keyBits , Long hsmProfileId ) throws KMSException ;
69+ String getProviderName () ;
5770
5871 /**
5972 * Create a new Key Encryption Key (KEK) in the secure backend.
@@ -69,6 +82,18 @@ default String createKek(KeyPurpose purpose, String label, int keyBits) throws K
6982 return createKek (purpose , label , keyBits , null );
7083 }
7184
85+ /**
86+ * Create a new Key Encryption Key (KEK) in the secure backend with explicit HSM profile.
87+ *
88+ * @param purpose the purpose/scope for this KEK
89+ * @param label human-readable label for the KEK (must be unique within purpose)
90+ * @param keyBits key size in bits (typically 128, 192, or 256)
91+ * @param hsmProfileId optional HSM profile ID to create the KEK in (null for auto-resolution/default)
92+ * @return the KEK identifier (label or handle) for later reference
93+ * @throws KMSException if KEK creation fails
94+ */
95+ String createKek (KeyPurpose purpose , String label , int keyBits , Long hsmProfileId ) throws KMSException ;
96+
7297 /**
7398 * Delete a KEK from the secure backend.
7499 * WARNING: This will make all DEKs wrapped by this KEK unrecoverable.
@@ -78,7 +103,6 @@ default String createKek(KeyPurpose purpose, String label, int keyBits) throws K
78103 */
79104 void deleteKek (String kekId ) throws KMSException ;
80105
81-
82106 /**
83107 * Check if a KEK exists and is accessible
84108 *
@@ -88,18 +112,6 @@ default String createKek(KeyPurpose purpose, String label, int keyBits) throws K
88112 */
89113 boolean isKekAvailable (String kekId ) throws KMSException ;
90114
91- /**
92- * Wrap (encrypt) a plaintext Data Encryption Key with a KEK using explicit HSM profile.
93- *
94- * @param plainDek the plaintext DEK to wrap (caller must zeroize after call)
95- * @param purpose the intended purpose of this DEK
96- * @param kekLabel the label of the KEK to use for wrapping
97- * @param hsmProfileId optional HSM profile ID to use (null for auto-resolution/default)
98- * @return WrappedKey containing the encrypted DEK and metadata
99- * @throws KMSException if wrapping fails or KEK not found
100- */
101- WrappedKey wrapKey (byte [] plainDek , KeyPurpose purpose , String kekLabel , Long hsmProfileId ) throws KMSException ;
102-
103115 /**
104116 * Wrap (encrypt) a plaintext Data Encryption Key with a KEK.
105117 * Delegates to {@link #wrapKey(byte[], KeyPurpose, String, Long)} with null profile ID.
@@ -115,16 +127,16 @@ default WrappedKey wrapKey(byte[] plainDek, KeyPurpose purpose, String kekLabel)
115127 }
116128
117129 /**
118- * Unwrap (decrypt) a wrapped DEK to obtain the plaintext key using explicit HSM profile.
119- * <p>
120- * SECURITY: Caller MUST zeroize the returned byte array after use
130+ * Wrap (encrypt) a plaintext Data Encryption Key with a KEK using explicit HSM profile.
121131 *
122- * @param wrappedKey the wrapped key to decrypt
132+ * @param plainDek the plaintext DEK to wrap (caller must zeroize after call)
133+ * @param purpose the intended purpose of this DEK
134+ * @param kekLabel the label of the KEK to use for wrapping
123135 * @param hsmProfileId optional HSM profile ID to use (null for auto-resolution/default)
124- * @return plaintext DEK (caller must zeroize!)
125- * @throws KMSException if unwrapping fails or KEK not found
136+ * @return WrappedKey containing the encrypted DEK and metadata
137+ * @throws KMSException if wrapping fails or KEK not found
126138 */
127- byte [] unwrapKey ( WrappedKey wrappedKey , Long hsmProfileId ) throws KMSException ;
139+ WrappedKey wrapKey ( byte [] plainDek , KeyPurpose purpose , String kekLabel , Long hsmProfileId ) throws KMSException ;
128140
129141 /**
130142 * Unwrap (decrypt) a wrapped DEK to obtain the plaintext key.
@@ -141,18 +153,16 @@ default byte[] unwrapKey(WrappedKey wrappedKey) throws KMSException {
141153 }
142154
143155 /**
144- * Generate a new random DEK and immediately wrap it with a KEK using explicit HSM profile.
145- * (convenience method combining generation + wrapping)
156+ * Unwrap (decrypt) a wrapped DEK to obtain the plaintext key using explicit HSM profile.
157+ * <p>
158+ * SECURITY: Caller MUST zeroize the returned byte array after use
146159 *
147- * @param purpose the intended purpose of the new DEK
148- * @param kekLabel the label of the KEK to use for wrapping
149- * @param keyBits DEK size in bits (typically 128, 192, or 256)
160+ * @param wrappedKey the wrapped key to decrypt
150161 * @param hsmProfileId optional HSM profile ID to use (null for auto-resolution/default)
151- * @return WrappedKey containing the newly generated and wrapped DEK
152- * @throws KMSException if generation or wrapping fails
162+ * @return plaintext DEK (caller must zeroize!)
163+ * @throws KMSException if unwrapping fails or KEK not found
153164 */
154- WrappedKey generateAndWrapDek (KeyPurpose purpose , String kekLabel , int keyBits ,
155- Long hsmProfileId ) throws KMSException ;
165+ byte [] unwrapKey (WrappedKey wrappedKey , Long hsmProfileId ) throws KMSException ;
156166
157167 /**
158168 * Generate a new random DEK and immediately wrap it with a KEK.
@@ -170,16 +180,18 @@ default WrappedKey generateAndWrapDek(KeyPurpose purpose, String kekLabel, int k
170180 }
171181
172182 /**
173- * Rewrap a DEK with a different KEK (used during key rotation) using explicit target HSM profile.
174- * This unwraps with the old KEK and wraps with the new KEK without exposing the plaintext DEK.
183+ * Generate a new random DEK and immediately wrap it with a KEK using explicit HSM profile.
184+ * (convenience method combining generation + wrapping)
175185 *
176- * @param oldWrappedKey the currently wrapped key
177- * @param newKekLabel the label of the new KEK to wrap with
178- * @param targetHsmProfileId optional target HSM profile ID to wrap with (null for auto-resolution/default)
179- * @return new WrappedKey encrypted with the new KEK
180- * @throws KMSException if rewrapping fails
186+ * @param purpose the intended purpose of the new DEK
187+ * @param kekLabel the label of the KEK to use for wrapping
188+ * @param keyBits DEK size in bits (typically 128, 192, or 256)
189+ * @param hsmProfileId optional HSM profile ID to use (null for auto-resolution/default)
190+ * @return WrappedKey containing the newly generated and wrapped DEK
191+ * @throws KMSException if generation or wrapping fails
181192 */
182- WrappedKey rewrapKey (WrappedKey oldWrappedKey , String newKekLabel , Long targetHsmProfileId ) throws KMSException ;
193+ WrappedKey generateAndWrapDek (KeyPurpose purpose , String kekLabel , int keyBits ,
194+ Long hsmProfileId ) throws KMSException ;
183195
184196 /**
185197 * Rewrap a DEK with a different KEK (used during key rotation).
@@ -195,6 +207,18 @@ default WrappedKey rewrapKey(WrappedKey oldWrappedKey, String newKekLabel) throw
195207 return rewrapKey (oldWrappedKey , newKekLabel , null );
196208 }
197209
210+ /**
211+ * Rewrap a DEK with a different KEK (used during key rotation) using explicit target HSM profile.
212+ * This unwraps with the old KEK and wraps with the new KEK without exposing the plaintext DEK.
213+ *
214+ * @param oldWrappedKey the currently wrapped key
215+ * @param newKekLabel the label of the new KEK to wrap with
216+ * @param targetHsmProfileId optional target HSM profile ID to wrap with (null for auto-resolution/default)
217+ * @return new WrappedKey encrypted with the new KEK
218+ * @throws KMSException if rewrapping fails
219+ */
220+ WrappedKey rewrapKey (WrappedKey oldWrappedKey , String newKekLabel , Long targetHsmProfileId ) throws KMSException ;
221+
198222 /**
199223 * Perform health check on the provider backend
200224 *
0 commit comments