View Javadoc
1   package cn.home1.oss.lib.common.crypto;
2   
3   import static cn.home1.oss.lib.common.crypto.CryptoConstants.ALGO_AES;
4   import static cn.home1.oss.lib.common.crypto.CryptoConstants.ALGO_RSA;
5   import static com.google.common.base.Preconditions.checkArgument;
6   
7   import io.jsonwebtoken.SignatureAlgorithm;
8   
9   import lombok.extern.slf4j.Slf4j;
10  
11  import org.bouncycastle.jce.provider.BouncyCastleProvider;
12  
13  import java.security.Provider;
14  
15  @Slf4j
16  public abstract class Cryptos {
17  
18    private static final Provider BOUNCY_CASTLE_PROVIDER = new BouncyCastleProvider();
19  
20    private Cryptos() {
21    }
22  
23    public static Provider provider() {
24      return BOUNCY_CASTLE_PROVIDER;
25    }
26  
27    @SuppressWarnings("unchecked")
28    public static <T extends EncodeCipher> T cipher(final KeyExpression keyExpression) {
29      final T result;
30      if (keyExpression == null || !keyExpression.isPresent()) {
31        result = null;
32      } else {
33        final String spec = keyExpression.getSpec();
34        if (spec.startsWith(ALGO_AES)) {
35          result = (T) new Aes(Cryptos.provider(), keyExpression);
36        } else if (spec.startsWith(ALGO_RSA)) {
37          result = (T) new Rsa(Cryptos.provider(), keyExpression);
38        } else {
39          SignatureAlgorithm.forName(spec);
40          result = (T) new Jwt(keyExpression);
41        }
42      }
43  
44      if (result != null) {
45        final String test = "test";
46        try {
47          checkArgument(test.equals(result.decrypt(result.encrypt(test))), "bad cipher, test failed");
48        } catch (final UnsupportedOperationException ignored) {
49          // ignored
50          log.trace("unsupported cipher operation", ignored);
51        }
52        try {
53          checkArgument(test.equals(result.decrypt(result.encrypt(test, 3600))), "bad cipher, test failed");
54        } catch (final UnsupportedOperationException ignored) {
55          // ignored
56          log.trace("unsupported cipher operation", ignored);
57        }
58      }
59  
60      return result;
61    }
62  
63    @SuppressWarnings("unchecked")
64    public static <T extends EncodeEncryptor> T encryptor(final KeyExpression keyExpression) {
65      final T result;
66      if (keyExpression == null || !keyExpression.isPresent()) {
67        result = null;
68      } else {
69        final String spec = keyExpression.getSpec();
70        if (spec.startsWith(ALGO_AES)) {
71          result = (T) new AesEncryptor(BOUNCY_CASTLE_PROVIDER, keyExpression);
72        } else if (spec.startsWith(ALGO_RSA)) {
73          result = (T) new RsaEncryptor(BOUNCY_CASTLE_PROVIDER, keyExpression);
74        } else {
75          SignatureAlgorithm.forName(spec);
76          result = (T) new JwtEncryptor(keyExpression);
77        }
78      }
79  
80      if (result != null) {
81        try {
82          result.encrypt("test");
83        } catch (final UnsupportedOperationException ignored) {
84          // ignored
85          log.trace("unsupported encryptor operation", ignored);
86        }
87        try {
88          result.encrypt("test", 3600);
89        } catch (final UnsupportedOperationException ignored) {
90          // ignored
91          log.trace("unsupported encryptor operation", ignored);
92        }
93      }
94  
95      return result;
96    }
97  
98    @SuppressWarnings("unchecked")
99    public static <T extends EncodeDecryptor> T decryptor(final KeyExpression keyExpression) {
100     final T result;
101     if (keyExpression == null || !keyExpression.isPresent()) {
102       result = null;
103     } else {
104       final String spec = keyExpression.getSpec();
105       if (spec.startsWith(ALGO_AES)) {
106         result = (T) new AesDecryptor(BOUNCY_CASTLE_PROVIDER, keyExpression);
107       } else if (spec.startsWith(ALGO_RSA)) {
108         result = (T) new RsaDecryptor(BOUNCY_CASTLE_PROVIDER, keyExpression);
109       } else {
110         SignatureAlgorithm.forName(spec);
111         result = (T) new JwtDecryptor(keyExpression);
112       }
113     }
114     return result;
115   }
116 }