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
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
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
85 log.trace("unsupported encryptor operation", ignored);
86 }
87 try {
88 result.encrypt("test", 3600);
89 } catch (final UnsupportedOperationException ignored) {
90
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 }