feat(outbound): SecretCipher - AES-GCM with JWT-derived key for at-rest secret encryption
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
package com.cameleer.server.app.outbound.crypto;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
class SecretCipherTest {
|
||||
private final SecretCipher cipher = new SecretCipher("test-jwt-secret-must-be-long-enough-to-derive");
|
||||
|
||||
@Test
|
||||
void roundTrips() {
|
||||
String plaintext = "my-hmac-secret-12345";
|
||||
String ct = cipher.encrypt(plaintext);
|
||||
assertThat(ct).isNotEqualTo(plaintext);
|
||||
assertThat(cipher.decrypt(ct)).isEqualTo(plaintext);
|
||||
}
|
||||
|
||||
@Test
|
||||
void differentCiphertextsForSamePlaintext() {
|
||||
String a = cipher.encrypt("x");
|
||||
String b = cipher.encrypt("x");
|
||||
assertThat(a).isNotEqualTo(b);
|
||||
assertThat(cipher.decrypt(a)).isEqualTo(cipher.decrypt(b));
|
||||
}
|
||||
|
||||
@Test
|
||||
void decryptRejectsTamperedCiphertext() {
|
||||
String ct = cipher.encrypt("abc");
|
||||
String tampered = ct.substring(0, ct.length() - 2) + "00";
|
||||
assertThatThrownBy(() -> cipher.decrypt(tampered))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
void decryptRejectsWrongKey() {
|
||||
String ct = cipher.encrypt("abc");
|
||||
SecretCipher other = new SecretCipher("some-other-jwt-secret-that-is-long-enough");
|
||||
assertThatThrownBy(() -> other.decrypt(ct))
|
||||
.isInstanceOf(IllegalArgumentException.class);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user