1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package davmail.util;
21
22 import davmail.Settings;
23
24 import javax.crypto.Cipher;
25 import javax.crypto.SecretKey;
26 import javax.crypto.SecretKeyFactory;
27 import javax.crypto.spec.IvParameterSpec;
28 import javax.crypto.spec.PBEKeySpec;
29 import javax.crypto.spec.PBEParameterSpec;
30 import java.io.IOException;
31 import java.nio.charset.StandardCharsets;
32 import java.security.NoSuchAlgorithmException;
33 import java.security.spec.InvalidKeySpecException;
34
35
36
37
38
39 public class StringEncryptor {
40 static final String ALGO = "PBEWithHmacSHA256AndAES_128";
41 static final String DEFAULT_FINGERPRINT = "davmailgateway!&";
42
43 private final String password;
44
45 public StringEncryptor(String password) {
46 this.password = password;
47 }
48
49 public String encryptString(String value) throws IOException {
50 try {
51 byte[] plaintext = value.getBytes(StandardCharsets.UTF_8);
52
53
54 Cipher enc = Cipher.getInstance(ALGO);
55 enc.init(Cipher.ENCRYPT_MODE, getSecretKey(), getPBEParameterSpec());
56 byte[] encrypted = enc.doFinal(plaintext);
57 return "{AES}" + IOUtil.encodeBase64AsString(encrypted);
58
59 } catch (Exception e) {
60 throw new IOException(e);
61 }
62 }
63
64 public String decryptString(String value) throws IOException {
65 if (value != null && value.startsWith("{AES}")) {
66 try {
67 byte[] encrypted = IOUtil.decodeBase64(value.substring(5));
68
69 Cipher dec = Cipher.getInstance(ALGO);
70 dec.init(Cipher.DECRYPT_MODE, getSecretKey(), getPBEParameterSpec());
71 byte[] decrypted = dec.doFinal(encrypted);
72 return new String(decrypted, StandardCharsets.UTF_8);
73
74 } catch (Exception e) {
75 throw new IOException(e);
76 }
77 } else {
78 return value;
79 }
80 }
81
82 private SecretKey getSecretKey() throws InvalidKeySpecException, NoSuchAlgorithmException {
83 PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
84
85 SecretKeyFactory kf = SecretKeyFactory.getInstance(ALGO);
86 return kf.generateSecret(keySpec);
87 }
88
89 private PBEParameterSpec getPBEParameterSpec() {
90 byte[] bytes = Settings.getProperty("davmail.oauth.fingerprint", DEFAULT_FINGERPRINT).getBytes(StandardCharsets.UTF_8);
91 return new PBEParameterSpec(bytes, 10000, new IvParameterSpec(bytes));
92 }
93 }