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  }