KeyAlgorithmEnu
KeyAlgorithmEnu
1 /**
2 * 系统支持的加密算法
3 */
4 public enum KeyAlgorithmEnu {
5 RSA("RSA"),
6 MD5withRSA("MD5withRSA"),
7 HmacSHA512("HmacSHA512"),
8 MD5("MD5"),
9 DESede("DESede"),//3DES
10 AES("AES")
11 ;
12 private String name;
13
14 KeyAlgorithmEnu(String name) {
15 this.name = name;
16 }
17
18 public String getName() {
19 return name;
20 }
21
MD5Utils
MD5Utils
1 /**
2 * MD5 encrypt utilities
3 */
4 public class MD5Utils {
5
6 /**
7 * MD5加密
8 * @param data
9 * @return
10 * @throws NoSuchAlgorithmException
11 */
12 public static byte[] encodeMD5(String data) throws NoSuchAlgorithmException {
13 MessageDigest md5=MessageDigest.getInstance(KeyAlgorithmEnu.MD5.getName());
14 return md5.digest(data.getBytes(StandardCharsets.UTF_8));
15 }
16
HmacUtils
HmacUtils
1 /**
2 * Hmac实现类
3 */
4 public class HmacUtils {
5 public static final String KEY_ALGORITHM_HMACSHA512 = KeyAlgorithmEnu.HmacSHA512.getName();
6 /**
7 * 初始化HmacSHA512的密钥
8 * @return String 密钥,base64编码
9 *
10 * */
11 public static String genHmacSHA512Key() throws NoSuchAlgorithmException {
12 //初始化KeyGenerator
13 KeyGenerator keyGenerator=KeyGenerator.getInstance(KEY_ALGORITHM_HMACSHA512);
14 //产生密钥
15 SecretKey secretKey=keyGenerator.generateKey();
16 //获取密钥
17 return Base64Utils.encryptBASE64(secretKey.getEncoded());
18 }
19 /**
20 * HmacSHA512消息摘要
21 * @param data 待做摘要处理的数据
22 * @param key 密钥, base64编码
23 * @return byte[] 消息摘要
24 * */
25 public static byte[] encodeHmacSHA512(byte[] data,String key) throws NoSuchAlgorithmException, InvalidKeyException {
26 //还原密钥,因为密钥是以byte形式为消息传递算法所拥有
27 SecretKey secretKey=new SecretKeySpec(Base64Utils.decryptBASE64(key),KEY_ALGORITHM_HMACSHA512);
28 //实例化Mac
29 Mac mac=Mac.getInstance(secretKey.getAlgorithm());
30 //初始化Mac
31 mac.init(secretKey);
32 //执行消息摘要处理
33 return mac.doFinal(data);
34 }
35 }
36 DESUtils
DESUtils
1 /**
2 * DES encrypt utilities
3 * <p>
4 * Note:
5 * 1. DES 对应key 要求24位,不足程序会按byte 0 补齐,超出位直接截取
6 * 2. DES 对应key 传入参数值默认是按base64编码处理
7 * </p>
8 */
9 public class DESUtils {
10 public final static String Algorithm_3DES = KeyAlgorithmEnu.DESede.getName();
11
12
13 /**
14 * 3DES 解密
15 * @param key base64 encode
16 * @param data 解密数据
17 * @return 返回解密胡的字节码数组
18 * @throws Exception
19 */
20 public static byte[] decode3DES(String key,byte[] data)throws Exception{
21 //base64 解码,24位key处理(不足24位byte 0 补齐,超过则截取)
22 byte[] newKey = truncatOrPaddingWithByteZero(Base64Utils.decryptBASE64(key),24);
23 //生成密钥
24 SecretKey deskey = new SecretKeySpec(newKey, Algorithm_3DES);
25 //解密
26 Cipher c1 = Cipher.getInstance(Algorithm_3DES);
27 c1.init(Cipher.DECRYPT_MODE, deskey);
28 return c1.doFinal(data);
29 }
30
31 /**
32 * 3DES 加密
33 * @param key base64 encode
34 * @param data 加密数据
35 * @return 返回加密后的字节码数组
36 * @throws Exception
37 */
38 public static byte[] encode3DES(String key, byte[] data) throws Exception {
39 //base64 解码,24位key处理(不足24位byte 0 补齐,超过则截取)
40 byte[] newKey = truncatOrPaddingWithByteZero(Base64Utils.decryptBASE64(key),24);
41 //生成密钥
42 SecretKey deskey = new SecretKeySpec(newKey, Algorithm_3DES);
43 //加密
44 Cipher c1 = Cipher.getInstance(Algorithm_3DES);
45 c1.init(Cipher.ENCRYPT_MODE, deskey);
46 return c1.doFinal(data);//在单一方面的加密或解密
47 }
48
49 /**
50 * 截取或填充指定长度的
51 * @param original
52 * @param size
53 * @return
54 */
55 private static byte[] truncatOrPaddingWithByteZero(byte[] original,int size) throws NoSuchAlgorithmException {
56 original = MD5Utils.encodeMD5(new String(original));
57 byte[] newKeyByte = Arrays.copyOf(original,size);
58 return newKeyByte;
59 }
60
61 }
62
Base64Utils
Base64Utils
1 public class Base64Utils {
2
3 /**
4 * base64解码
5 * @param data
6 * @return
7 */
8 public static byte[] decryptBASE64(String data){
9 return Base64.getDecoder().decode(data.getBytes(StandardCharsets.UTF_8));
10 }
11
12 /**
13 * base64编码
14 * @param data
15 * @return
16 */
17 public static String encryptBASE64(byte[] data){
18 return new String(Base64.getEncoder().encode(data), StandardCharsets.UTF_8);
19 }
20
AESUtils
AESUtils
1 /**
2 * AES encrypt utilities - 对称加密算法实现,可逆
3 * <p>
4 * Note:
5 * 1. AES 对应key 要求16位,不足程序会按byte 0 补齐,超出位直接截取
6 * 2. AES 对应key 传入参数值默认是按base64编码处理
7 * </p>
8 */
9 public class AESUtils {
10 public final static String Algorithm_AES = KeyAlgorithmEnu.AES.getName();
11 private final static int KEY_SIZE = 128; //不要随便修改,des的key和这个值是绑定的。默认对应的key为16位
12
13 /**
14 * AES 加密
15 * @param key base64编码
16 * @param data 加密数据
17 * @return
18 * @throws Exception
19 */
20 public static byte[] encodeAES(String key, byte[] data) throws Exception {
21 KeyGenerator kgen = KeyGenerator.getInstance(Algorithm_AES);
22 //base64 解码,16位key处理(不足16位byte 0 补齐,超过则截取)
23 byte[] newKey = truncatOrPaddingWithByteZero(Base64Utils.decryptBASE64(key),16);
24 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
25 secureRandom.setSeed(newKey);
26 kgen.init(KEY_SIZE, secureRandom);
27 SecretKey secretKey = kgen.generateKey();
28 byte[] enCodeFormat = secretKey.getEncoded();
29 SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, Algorithm_AES);
30 Cipher cipher = Cipher.getInstance(Algorithm_AES);// 创建密码器
31 cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);// 初始化
32 return cipher.doFinal(data); // 加密
33 }
34
35 /**
36 * AES 解密
37 * @param key base64编码
38 * @param data 解密数据
39 * @return
40 * @throws Exception
41 */
42 public static byte[] decodeAES(String key, byte[] data) throws Exception {
43 KeyGenerator kgen = KeyGenerator.getInstance(Algorithm_AES);
44 //base64 解码,16位key处理(不足16位byte 0 补齐,超过则截取)
45 byte[] newKey = truncatOrPaddingWithByteZero(Base64Utils.decryptBASE64(key),16);
46 SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG" );
47 secureRandom.setSeed(newKey);
48 kgen.init(KEY_SIZE, secureRandom);
49 SecretKey secretKey = kgen.generateKey();
50 byte[] enCodeFormat = secretKey.getEncoded();
51 SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, Algorithm_AES);
52 Cipher cipher = Cipher.getInstance(Algorithm_AES);// 创建密码器
53 cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);// 初始化
54 return cipher.doFinal(data);
55 }
56
57 /**
58 * 截取或填充指定长度的
59 * @param original
60 * @param size
61 * @return
62 */
63 private static byte[] truncatOrPaddingWithByteZero(byte[] original,int size) throws NoSuchAlgorithmException {
64 original = MD5Utils.encodeMD5(new String(original));
65 byte[] newKeyByte = Arrays.copyOf(original,size);
66 return newKeyByte;
67 }
68 }
69
RSACoder类
RSACoder
1 /**
2 * eagle-daiq 2017-05-28
3 * RSA算法实现类, 细节见单元测试RSACoderTest类
4 * <p>
5 * 使用方式:
6 * RSACoder rsaCoder = new RSACoder();
7 * //初始化 秘钥
8 * rsaCoder.initKeyFromFile("cqfaeuser.cer","cqfaeuser.jks","cqfaeuser","123456");
9 * String publicKey = rsaCoder.getPublicKey();//取公钥,base64编码
10 * String privateKey = rsaCoder.getPrivateKey();//取私钥, base64编码
11 * //公钥加密
12 * byte[] encodedData = rsaCoder.encryptByPublicKey(data, publicKey);
13 * //私钥解密
14 * byte[] decodedData = rsaCoder.decryptByPrivateKey(encodedData,privateKey);
15 * </p>
16 */
17 public class RSACoder {
18 public static final String KEY_ALGORITHM = KeyAlgorithmEnu.RSA.getName();
19 public static final String SIGNATURE_ALGORITHM = KeyAlgorithmEnu.MD5withRSA.getName();
20
21 private static final String PUBLIC_KEY = "RSAPublicKey";
22 private static final String PRIVATE_KEY = "RSAPrivateKey";
23 private Map<String, Object> keyMap = new HashMap<>();
24
25 public RSACoder() {
26 }
27
28 public RSACoder(String publicKeyFile,String keyStoreFile,String alias,String password) {
29 this.initKeyFromFile(publicKeyFile,keyStoreFile,alias,password);
30 }
31
32 /**
33 * 用私钥对信息生成数字签名
34 *
35 * @param data
36 * 加密数据
37 * @param privateKey
38 * 私钥 base64编码
39 *
40 * @return
41 * @throws Exception
42 */
43 public String sign(byte[] data, String privateKey) throws Exception {
44 // 解密由base64编码的私钥
45 byte[] keyBytes = Base64Utils.decryptBASE64(privateKey);
46
47 // 构造PKCS8EncodedKeySpec对象
48 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
49
50 // KEY_ALGORITHM 指定的加密算法
51 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
52
53 // 取私钥匙对象
54 PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
55
56 // 用私钥对信息生成数字签名
57 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
58 signature.initSign(priKey);
59 signature.update(data);
60
61 return Base64Utils.encryptBASE64(signature.sign());
62 }
63
64 /**
65 * 校验数字签名
66 *
67 * @param data
68 * 加密数据
69 * @param publicKey
70 * 公钥 base64编码
71 * @param sign
72 * 数字签名
73 *
74 * @return 校验成功返回true 失败返回false
75 * @throws Exception
76 *
77 */
78 public boolean verify(byte[] data, String publicKey, String sign)
79 throws Exception {
80
81 // 解密由base64编码的公钥
82 byte[] keyBytes = Base64Utils.decryptBASE64(publicKey);
83
84 // 构造X509EncodedKeySpec对象
85 X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
86
87 // KEY_ALGORITHM 指定的加密算法
88 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
89
90 // 取公钥匙对象
91 PublicKey pubKey = keyFactory.generatePublic(keySpec);
92
93 Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
94 signature.initVerify(pubKey);
95 signature.update(data);
96
97 // 验证签名是否正常
98 return signature.verify(Base64Utils.decryptBASE64(sign));
99 }
100
101 /**
102 * 解密<br>
103 * 用私钥解密
104 *
105 * @param data
106 * @param key base64编码
107 * @return
108 * @throws Exception
109 */
110 public byte[] decryptByPrivateKey(byte[] data, String key)
111 throws Exception {
112 // 对密钥解密
113 byte[] keyBytes = Base64Utils.decryptBASE64(key);
114
115 // 取得私钥
116 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
117 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
118 Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
119
120 // 对数据解密
121 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
122 cipher.init(Cipher.DECRYPT_MODE, privateKey);
123
124 return cipher.doFinal(data);
125 }
126
127 /**
128 * 解密<br>
129 * 用公钥解密
130 *
131 * @param data
132 * @param key base64编码
133 * @return
134 * @throws Exception
135 */
136 public byte[] decryptByPublicKey(byte[] data, String key)
137 throws Exception {
138 // 对密钥解密
139 byte[] keyBytes = Base64Utils.decryptBASE64(key);
140
141 // 取得公钥
142 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
143 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
144 Key publicKey = keyFactory.generatePublic(x509KeySpec);
145
146 // 对数据解密
147 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
148 cipher.init(Cipher.DECRYPT_MODE, publicKey);
149
150 return cipher.doFinal(data);
151 }
152
153 /**
154 * 加密<br>
155 * 用公钥加密
156 *
157 * @param data
158 * @param key base64编码
159 * @return
160 * @throws Exception
161 */
162 public byte[] encryptByPublicKey(byte[] data, String key)
163 throws Exception {
164 // 对公钥解密
165 byte[] keyBytes = Base64Utils.decryptBASE64(key);
166
167 // 取得公钥
168 X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
169 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
170 Key publicKey = keyFactory.generatePublic(x509KeySpec);
171
172 // 对数据加密
173 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
174 cipher.init(Cipher.ENCRYPT_MODE, publicKey);
175
176 return cipher.doFinal(data);
177 }
178
179 /**
180 * 加密<br>
181 * 用私钥加密
182 *
183 * @param data
184 * @param key base64编码
185 * @return
186 * @throws Exception
187 */
188 public byte[] encryptByPrivateKey(byte[] data, String key)
189 throws Exception {
190 // 对密钥解密
191 byte[] keyBytes = Base64Utils.decryptBASE64(key);
192
193 // 取得私钥
194 PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
195 KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
196 Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
197
198 // 对数据加密
199 Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
200 cipher.init(Cipher.ENCRYPT_MODE, privateKey);
201
202 return cipher.doFinal(data);
203 }
204
205 /**
206 * 取得私钥,base64编码
207 *
208 * @return
209 * @throws Exception
210 */
211 public String getPrivateKey()
212 throws Exception {
213 Key key = (Key) keyMap.get(PRIVATE_KEY);
214
215 return Base64Utils.encryptBASE64(key.getEncoded());
216 }
217
218 /**
219 * 取得公钥,base64编码
220 *
221 * @return
222 * @throws Exception
223 */
224 public String getPublicKey()
225 throws Exception {
226 Key key = (Key) keyMap.get(PUBLIC_KEY);
227
228 return Base64Utils.encryptBASE64(key.getEncoded());
229 }
230
231 /**
232 * 从文件加载base64的公钥串
233 * @see #loadPublicKeyByFile(String)
234 * @param filePath
235 * @return
236 */
237 public String loadBase64PublicKeyByFile(String filePath){
238 return Base64Utils.encryptBASE64(loadPublicKeyByFile(filePath).getEncoded());
239 }
240
241 /**
242 * 从文件加载公钥
243 * @param filepath
244 * @return
245 */
246 public PublicKey loadPublicKeyByFile(String filepath) {
247 try {
248 //通过证书,获取公钥
249 CertificateFactory cf = CertificateFactory.getInstance("X.509");
250 Certificate c = cf.generateCertificate(FileUtils.getFileStream(filepath));
251 PublicKey publicKey = c.getPublicKey();
252 return publicKey;
253 } catch (Exception e) {
254 throw new RuntimeException(String.format("公钥数据流file=%s读取错误",filepath),e);
255 }
256 }
257
258 /**
259 * 从文件加载base64私钥串
260 * @see #loadBase64PrivateKeyByFile(String, String, String)
261 * @param filepath
262 * @param alias
263 * @param password
264 * @return
265 */
266 public String loadBase64PrivateKeyByFile(String filepath, String alias, String password){
267 return Base64Utils.encryptBASE64(loadPrivateKeyByFile(filepath,alias,password).getEncoded());
268 }
269 /**
270 * 从文件加载私钥
271 * @param filepath java 私钥库文件
272 * @param alias 私钥别名
273 * @param password 私钥密码
274 * @return
275 */
276 public PrivateKey loadPrivateKeyByFile(String filepath, String alias, String password){
277 try {
278 KeyStore ks= KeyStore.getInstance("JKS");
279 ks.load(FileUtils.getFileStream(filepath), password.toCharArray());
280
281 PrivateKey privateKey = (PrivateKey)ks.getKey(alias, password.toCharArray());
282 return privateKey;
283 } catch (Exception e) {
284 throw new RuntimeException(String.format("私钥数据流[file=%s,alias=%s]读取错误",filepath,alias),e);
285 }
286 }
287
288 /**
289 * 初始化密钥 - 程序自动生成公私秘钥
290 *
291 * @return
292 * @throws Exception
293 */
294 public void initDefaultKey() throws Exception {
295 KeyPairGenerator keyPairGen = KeyPairGenerator
296 .getInstance(KEY_ALGORITHM);
297 keyPairGen.initialize(2048);
298
299 KeyPair keyPair = keyPairGen.generateKeyPair();
300
301 // 公钥
302 RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
303
304 // 私钥
305 RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
306
307
308 keyMap.put(PUBLIC_KEY, publicKey);
309 keyMap.put(PRIVATE_KEY, privateKey);
310 }
311
312 /**
313 * 从文件初始化公私秘钥
314 * @param publicKeyFile 公钥文件
315 * @param keyStoreFile 秘钥库文件
316 * @param alias 秘钥别名
317 * @param password 秘钥库密码
318 */
319 public void initKeyFromFile(String publicKeyFile,String keyStoreFile,String alias,String password){
320 keyMap.put(PUBLIC_KEY, this.loadPublicKeyByFile(publicKeyFile));
321 keyMap.put(PRIVATE_KEY, this.loadPrivateKeyByFile(keyStoreFile,alias,password));
322 }
323
FileUtils类
FileUtils
1 /**
2 * eagle-daiq 2017-05-28
3 */
4 public class FileUtils {
5
6 public static InputStream getFileStream(String filePath){
7 InputStream is = null;
8 try {
9 is = new FileInputStream(filePath);
10 } catch (FileNotFoundException e) {
11 System.out.println(String.format("文件%s加载失败,尝试类路径加载",filePath));
12 }
13 if(is == null){
14 is = FileUtils.class.getResourceAsStream(filePath);
15 }
16 if (is == null) {
17 is = FileUtils.class.getClassLoader().getResourceAsStream(filePath);
18 }
19 if (is == null) {
20 is = ClassLoader.getSystemResourceAsStream(filePath);
21 }
22 if(is == null){
23 throw new RuntimeException(String.format("文件filePath=%s读取错误",filePath));
24 }
25 System.out.println(String.format("文件%s加载成功.",filePath));
26 return is;
27 }
28 }
29
---------------------
月下孤城
mail:eagle_daiqiang@sina.com