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 javax.crypto.Cipher;
23 import javax.crypto.SecretKey;
24 import javax.crypto.SecretKeyFactory;
25 import javax.crypto.spec.IvParameterSpec;
26 import javax.crypto.spec.PBEKeySpec;
27 import javax.crypto.spec.PBEParameterSpec;
28 import java.io.IOException;
29 import java.net.InetAddress;
30 import java.nio.charset.StandardCharsets;
31 import java.security.NoSuchAlgorithmException;
32 import java.security.spec.InvalidKeySpecException;
33
34
35
36
37
38 public class StringEncryptor {
39 static final String ALGO = "PBEWithHmacSHA256AndAES_128";
40 static String fingerprint;
41
42 static {
43 try {
44 fingerprint = InetAddress.getLocalHost().getCanonicalHostName().substring(0, 16);
45 } catch (Throwable t) {
46 fingerprint = "davmailgateway!&";
47 }
48 }
49
50 private final String password;
51
52 public StringEncryptor(String password) {
53 this.password = password;
54 }
55
56 public String encryptString(String value) throws IOException {
57 try {
58 byte[] plaintext = value.getBytes(StandardCharsets.UTF_8);
59
60
61 Cipher enc = Cipher.getInstance(ALGO);
62 enc.init(Cipher.ENCRYPT_MODE, getSecretKey(), getPBEParameterSpec());
63 byte[] encrypted = enc.doFinal(plaintext);
64 return "{AES}" + IOUtil.encodeBase64AsString(encrypted);
65
66 } catch (Exception e) {
67 throw new IOException(e);
68 }
69 }
70
71 public String decryptString(String value) throws IOException {
72 if (value != null && value.startsWith("{AES}")) {
73 try {
74 byte[] encrypted = IOUtil.decodeBase64(value.substring(5));
75
76 Cipher dec = Cipher.getInstance(ALGO);
77 dec.init(Cipher.DECRYPT_MODE, getSecretKey(), getPBEParameterSpec());
78 byte[] decrypted = dec.doFinal(encrypted);
79 return new String(decrypted, StandardCharsets.UTF_8);
80
81 } catch (Exception e) {
82 throw new IOException(e);
83 }
84 } else {
85 return value;
86 }
87 }
88
89 private SecretKey getSecretKey() throws InvalidKeySpecException, NoSuchAlgorithmException {
90 PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
91
92 SecretKeyFactory kf = SecretKeyFactory.getInstance(ALGO);
93 return kf.generateSecret(keySpec);
94 }
95
96 private PBEParameterSpec getPBEParameterSpec() {
97 byte[] bytes = fingerprint.getBytes(StandardCharsets.UTF_8);
98 return new PBEParameterSpec(bytes, 10000, new IvParameterSpec(bytes));
99 }
100 }