implemented EncryptedMailConfig, needs testing
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
22
de.srsoftware.oidc.datastore.encrypted/build.gradle
Normal file
22
de.srsoftware.oidc.datastore.encrypted/build.gradle
Normal 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()
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user