implemented EncryptedMailConfig, needs testing

Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
2024-09-26 20:39:53 +02:00
parent ae38f489b8
commit 8debdc781b
8 changed files with 227 additions and 1 deletions

View File

@@ -0,0 +1,22 @@
plugins {
id 'java'
}
group = 'de.srsoftware'
version = '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
dependencies {
testImplementation platform('org.junit:junit-bom:5.10.0')
testImplementation 'org.junit.jupiter:junit-jupiter'
implementation project(':de.srsoftware.oidc.api')
implementation 'com.sun.mail:jakarta.mail:2.0.1'
}
test {
useJUnitPlatform()
}

View File

@@ -0,0 +1,71 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.datastore.encrypted;
import static java.nio.charset.StandardCharsets.UTF_8;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.KeySpec;
import java.util.Base64;
import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
public class EncryptedConfig {
private final Cipher cipher;
private static final int KEY_LENGTH = 256;
private static final int ITERATION_COUNT = 65536;
private final SecretKeySpec secretKeySpec;
public EncryptedConfig(String key, String salt) {
try {
SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
KeySpec spec = new PBEKeySpec(key.toCharArray(), salt.getBytes(), ITERATION_COUNT, KEY_LENGTH);
SecretKey tmp = factory.generateSecret(spec);
secretKeySpec = new SecretKeySpec(tmp.getEncoded(), "AES");
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
} catch (NoSuchPaddingException | NoSuchAlgorithmException | InvalidKeySpecException ex) {
throw new RuntimeException(ex);
}
}
public String encrypt(String plain) {
SecureRandom secureRandom = new SecureRandom();
byte[] iv = new byte[16];
secureRandom.nextBytes(iv);
IvParameterSpec initVector = new IvParameterSpec(iv);
try {
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, initVector);
byte[] cipherText = cipher.doFinal(plain.getBytes(UTF_8));
byte[] encryptedData = new byte[iv.length + cipherText.length];
System.arraycopy(iv, 0, encryptedData, 0, iv.length);
System.arraycopy(cipherText, 0, encryptedData, iv.length, cipherText.length);
return Base64.getEncoder().encodeToString(encryptedData);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public String decrypt(String secret) {
byte[] encryptedData = Base64.getDecoder().decode(secret);
byte[] iv = new byte[16];
System.arraycopy(encryptedData, 0, iv, 0, iv.length);
IvParameterSpec ivspec = new IvParameterSpec(iv);
try {
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivspec);
byte[] cipherText = new byte[encryptedData.length - 16];
System.arraycopy(encryptedData, 16, cipherText, 0, cipherText.length);
byte[] decryptedText = cipher.doFinal(cipherText);
return new String(decryptedText, UTF_8);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -0,0 +1,105 @@
/* © SRSoftware 2024 */
package de.srsoftware.oidc.datastore.encrypted;
/* © SRSoftware 2024 */
import static de.srsoftware.oidc.api.Constants.*;
import de.srsoftware.oidc.api.MailConfig;
import jakarta.mail.Authenticator;
import jakarta.mail.PasswordAuthentication;
public class EncryptedMailConfig extends EncryptedConfig implements MailConfig {
private final MailConfig storage;
private Authenticator auth;
public EncryptedMailConfig(MailConfig storage, String encryotionKey, String salt) {
super(encryotionKey, salt);
this.storage = storage;
}
@Override
public MailConfig save() {
return storage.save();
}
@Override
public String senderAddress() {
return decrypt(storage.senderAddress());
}
@Override
public MailConfig senderAddress(String newValue) {
storage.senderAddress(encrypt(newValue));
return this;
}
@Override
public String senderPassword() {
return decrypt(storage.senderPassword());
}
@Override
public MailConfig senderPassword(String newValue) {
storage.senderPassword(encrypt(newValue));
return this;
}
@Override
public boolean smtpAuth() {
return storage.smtpAuth();
}
@Override
public MailConfig smtpAuth(boolean newValue) {
storage.smtpAuth(newValue);
return this;
}
@Override
public Authenticator authenticator() {
if (auth == null) {
auth = new Authenticator() {
// override the getPasswordAuthentication method
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(senderAddress(), senderPassword());
}
};
}
return auth;
}
@Override
public String smtpHost() {
return decrypt(storage.smtpHost());
}
@Override
public MailConfig smtpHost(String newValue) {
storage.smtpHost(encrypt(newValue));
return this;
}
@Override
public int smtpPort() {
return storage.smtpPort();
}
@Override
public MailConfig smtpPort(int newValue) {
storage.smtpPort(newValue);
return this;
}
@Override
public boolean startTls() {
return storage.startTls();
}
@Override
public MailConfig startTls(boolean newValue) {
storage.startTls(newValue);
return this;
}
}