added encryption to app
This commit is contained in:
parent
a6add75201
commit
d647ecb8a1
|
@ -36,7 +36,7 @@ public class SecretController {
|
||||||
// create secret REST API
|
// create secret REST API
|
||||||
@CrossOrigin(origins = "${CROSS_ORIGIN}")
|
@CrossOrigin(origins = "${CROSS_ORIGIN}")
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public ResponseEntity<String> createSecret2(@Valid @RequestBody NewSecret newSecret, BindingResult bindingResult) {
|
public ResponseEntity<String> createSecret(@Valid @RequestBody NewSecret newSecret, BindingResult bindingResult) {
|
||||||
//input validation
|
//input validation
|
||||||
if (bindingResult.hasErrors()) {
|
if (bindingResult.hasErrors()) {
|
||||||
List<String> errors = bindingResult.getFieldErrors().stream()
|
List<String> errors = bindingResult.getFieldErrors().stream()
|
||||||
|
@ -61,7 +61,7 @@ public class SecretController {
|
||||||
Secret secret = new Secret(
|
Secret secret = new Secret(
|
||||||
null,
|
null,
|
||||||
user.getId(),
|
user.getId(),
|
||||||
new EncryptUtil(newSecret.getEncryptPassword()).encrypt(newSecret.getContent().toString())
|
new EncryptUtil(newSecret.getEncryptPassword()).encrypt(newSecret.getContent())
|
||||||
);
|
);
|
||||||
//save secret in db
|
//save secret in db
|
||||||
secretService.createSecret(secret);
|
secretService.createSecret(secret);
|
||||||
|
@ -195,7 +195,7 @@ public class SecretController {
|
||||||
Secret secret = new Secret(
|
Secret secret = new Secret(
|
||||||
secretId,
|
secretId,
|
||||||
user.getId(),
|
user.getId(),
|
||||||
new EncryptUtil(newSecret.getEncryptPassword()).encrypt(newSecret.getContent().toString())
|
new EncryptUtil(newSecret.getEncryptPassword()).encrypt(newSecret.getContent())
|
||||||
);
|
);
|
||||||
Secret updatedSecret = secretService.updateSecret(secret);
|
Secret updatedSecret = secretService.updateSecret(secret);
|
||||||
//save secret in db
|
//save secret in db
|
||||||
|
|
|
@ -1,28 +1,126 @@
|
||||||
package ch.bbw.pr.tresorbackend.util;
|
package ch.bbw.pr.tresorbackend.util;
|
||||||
|
|
||||||
import org.jasypt.util.text.AES256TextEncryptor;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
|
import com.fasterxml.jackson.databind.JsonNode;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Base64;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EncryptUtil
|
* EncryptUtil
|
||||||
* Used to encrypt content.
|
* Used to encrypt content.
|
||||||
* Not implemented yet.
|
* Not implemented yet.
|
||||||
|
*
|
||||||
* @author Peter Rutschmann
|
* @author Peter Rutschmann
|
||||||
*/
|
*/
|
||||||
public class EncryptUtil {
|
public class EncryptUtil {
|
||||||
|
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
|
||||||
|
private SecretKey secretKey;
|
||||||
|
|
||||||
//todo ergänzen!
|
public EncryptUtil(String secretKey) {
|
||||||
|
System.out.println(secretKey);
|
||||||
|
this.secretKey = generateKey(secretKey);
|
||||||
|
}
|
||||||
|
|
||||||
public EncryptUtil(String secretKey) {
|
public String encrypt(JsonNode content) {
|
||||||
//todo ergänzen!
|
return changeRelevantValues(content, str -> encryptString(str, secretKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
public String encrypt(String data) {
|
public String decrypt(String data) {
|
||||||
//todo anpassen!
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String decrypt(String data) {
|
try {
|
||||||
//todo anpassen!
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
return data;
|
JsonNode jsonNode = mapper.readTree(data);
|
||||||
}
|
return changeRelevantValues(jsonNode, str -> decryptString(str, secretKey));
|
||||||
|
} catch (JsonProcessingException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String changeRelevantValues(JsonNode content, Function<String, String> encryptOrDecrypt) {
|
||||||
|
if (!content.isObject()) return null;
|
||||||
|
ObjectNode objContent = (ObjectNode) content;
|
||||||
|
|
||||||
|
String passwordTextValue = objContent.get("password").textValue();
|
||||||
|
objContent.put("password", encryptOrDecrypt.apply(passwordTextValue));
|
||||||
|
|
||||||
|
String userNameTextValue = objContent.get("userName").textValue();
|
||||||
|
objContent.put("userName", encryptOrDecrypt.apply(userNameTextValue));
|
||||||
|
|
||||||
|
String urlTextValue = objContent.get("url").textValue();
|
||||||
|
objContent.put("url", encryptOrDecrypt.apply(urlTextValue));
|
||||||
|
|
||||||
|
return objContent.toPrettyString();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static String encryptString(String plainText, SecretKey key) {
|
||||||
|
try {
|
||||||
|
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||||
|
|
||||||
|
// Generate a random IV for CBC mode
|
||||||
|
byte[] iv = new byte[16];
|
||||||
|
SecureRandom.getInstanceStrong().nextBytes(iv);
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
|
||||||
|
byte[] encryptedBytes = cipher.doFinal(plainText.getBytes("UTF-8"));
|
||||||
|
|
||||||
|
// Prepend the IV to the ciphertext (IV doesn't need to be secret)
|
||||||
|
byte[] combined = new byte[iv.length + encryptedBytes.length];
|
||||||
|
System.arraycopy(iv, 0, combined, 0, iv.length);
|
||||||
|
System.arraycopy(encryptedBytes, 0, combined, iv.length, encryptedBytes.length);
|
||||||
|
|
||||||
|
return Base64.getEncoder().encodeToString(combined);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Encryption failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String decryptString(String encryptedText, SecretKey key) {
|
||||||
|
try {
|
||||||
|
byte[] combined = Base64.getDecoder().decode(encryptedText);
|
||||||
|
|
||||||
|
if (combined.length <= 16) {
|
||||||
|
throw new IllegalArgumentException("Invalid ciphertext (too short)");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract IV (first 16 bytes)
|
||||||
|
byte[] iv = new byte[16];
|
||||||
|
System.arraycopy(combined, 0, iv, 0, iv.length);
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||||
|
|
||||||
|
// Extract ciphertext (remaining bytes)
|
||||||
|
byte[] ciphertext = new byte[combined.length - iv.length];
|
||||||
|
System.arraycopy(combined, iv.length, ciphertext, 0, ciphertext.length);
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
|
||||||
|
byte[] decryptedBytes = cipher.doFinal(ciphertext);
|
||||||
|
|
||||||
|
return new String(decryptedBytes, "UTF-8");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Decryption failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SecretKey generateKey(String seed) {
|
||||||
|
try {
|
||||||
|
byte[] keyBytes = new byte[16];
|
||||||
|
byte[] seedBytes = seed.getBytes(StandardCharsets.UTF_8);
|
||||||
|
System.arraycopy(seedBytes, 0, keyBytes, 0, Math.min(seedBytes.length, keyBytes.length));
|
||||||
|
return new SecretKeySpec(keyBytes, "AES");
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("Key generation error.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue