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"; | ||||||
|    //todo ergänzen! |     private SecretKey secretKey; | ||||||
| 
 | 
 | ||||||
|     public EncryptUtil(String secretKey) { |     public EncryptUtil(String secretKey) { | ||||||
|       //todo ergänzen! |         System.out.println(secretKey); | ||||||
|  |         this.secretKey = generateKey(secretKey); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|    public String encrypt(String data) { |     public String encrypt(JsonNode content) { | ||||||
|       //todo anpassen! |         return changeRelevantValues(content, str -> encryptString(str, secretKey)); | ||||||
|       return data; |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     public String decrypt(String data) { |     public String decrypt(String data) { | ||||||
|       //todo anpassen! | 
 | ||||||
|       return data; |         try { | ||||||
|  |             ObjectMapper mapper = new ObjectMapper(); | ||||||
|  |             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