/jstarcraft-core-common/src/main/java/com/jstarcraft/core/common/security/SecurityUtility.java

https://github.com/HongZhaoHua/jstarcraft-core · Java · 427 lines · 233 code · 37 blank · 157 comment · 0 complexity · c80f6e6d46c3a464eae3d13b06aa6160 MD5 · raw file

  1. package com.jstarcraft.core.common.security;
  2. import java.security.KeyFactory;
  3. import java.security.KeyPair;
  4. import java.security.KeyPairGenerator;
  5. import java.security.MessageDigest;
  6. import java.security.PrivateKey;
  7. import java.security.PublicKey;
  8. import java.security.SecureRandom;
  9. import java.security.spec.PKCS8EncodedKeySpec;
  10. import java.security.spec.X509EncodedKeySpec;
  11. import java.util.Arrays;
  12. import javax.crypto.Cipher;
  13. import javax.crypto.KeyGenerator;
  14. import javax.crypto.SecretKey;
  15. import javax.crypto.SecretKeyFactory;
  16. import javax.crypto.spec.DESKeySpec;
  17. import javax.crypto.spec.SecretKeySpec;
  18. import org.apache.commons.codec.binary.Base64;
  19. import org.apache.commons.codec.binary.Hex;
  20. import com.jstarcraft.core.utility.KeyValue;
  21. import com.jstarcraft.core.utility.StringUtility;
  22. /**
  23. * 安全工具(主要涉及加密/解密)
  24. *
  25. * @author Birdy
  26. *
  27. */
  28. public class SecurityUtility {
  29. private static final String AES = "AES";
  30. private static final String Blowfish = "Blowfish";
  31. private static final String DES = "DES";
  32. private static final String RSA = "RSA";
  33. private static final String MD5 = "MD5";
  34. private static final String SHA1 = "SHA-1";
  35. private static final String SHA224 = "SHA-224";
  36. private static final String SHA256 = "SHA-256";
  37. private static final String SHA384 = "SHA-384";
  38. private static final String SHA512 = "SHA-512";
  39. /**
  40. * 字节转换为十六进制
  41. *
  42. * @param data
  43. * @return
  44. */
  45. public static String byte2Hex(byte[] data) {
  46. try {
  47. return Hex.encodeHexString(data);
  48. } catch (Exception exception) {
  49. String message = StringUtility.format("[{}]:字节转换为十六进制异常", Arrays.toString(data));
  50. throw new RuntimeException(message, exception);
  51. }
  52. }
  53. /**
  54. * 十六进制转换为字节
  55. *
  56. * @param data
  57. * @return
  58. */
  59. public static byte[] hex2Byte(String data) {
  60. try {
  61. return Hex.decodeHex(data.toCharArray());
  62. } catch (Exception exception) {
  63. String message = StringUtility.format("[{}]:十六进制转换为字节异常", data);
  64. throw new RuntimeException(message, exception);
  65. }
  66. }
  67. /**
  68. * 使用Base64对指定数据编码
  69. *
  70. * @param data
  71. * @return
  72. */
  73. public static String encodeBase64(byte[] data) {
  74. return Base64.encodeBase64String(data);
  75. }
  76. /**
  77. * 使用Base64对指定数据解码
  78. *
  79. * @param data
  80. * @return
  81. */
  82. public static byte[] decodeBase64(String data) {
  83. return Base64.decodeBase64(data);
  84. }
  85. /**
  86. * 获取AES对称秘钥
  87. *
  88. * @return
  89. */
  90. public static byte[] getAes() {
  91. return getAes(new SecureRandom());
  92. }
  93. /**
  94. * 获取AES对称秘钥
  95. *
  96. * @param random
  97. * @return
  98. */
  99. public static byte[] getAes(SecureRandom random) {
  100. try {
  101. KeyGenerator aes = KeyGenerator.getInstance(AES);
  102. aes.init(random);
  103. SecretKey key = aes.generateKey();
  104. return key.getEncoded();
  105. } catch (Exception exception) {
  106. String message = StringUtility.format("获取AES密匙异常:[{}]");
  107. throw new RuntimeException(message, exception);
  108. }
  109. }
  110. /**
  111. * AES加密
  112. *
  113. * @param data
  114. * @param key
  115. * @return
  116. */
  117. public static byte[] encryptAes(final byte[] data, final byte[] key) {
  118. try {
  119. SecretKeySpec secretKey = new SecretKeySpec(key, AES);
  120. Cipher cipher = Cipher.getInstance(AES);
  121. cipher.init(Cipher.ENCRYPT_MODE, secretKey);
  122. return cipher.doFinal(data);
  123. } catch (Exception exception) {
  124. String message = StringUtility.format("AES加密数据异常:[{}]", Arrays.toString(data));
  125. throw new RuntimeException(message, exception);
  126. }
  127. }
  128. /**
  129. * AES解密
  130. *
  131. * @param data
  132. * @param key
  133. * @return
  134. */
  135. public static byte[] decryptAes(final byte[] data, final byte[] key) {
  136. try {
  137. SecretKeySpec secretKey = new SecretKeySpec(key, AES);
  138. Cipher cipher = Cipher.getInstance(AES);
  139. cipher.init(Cipher.DECRYPT_MODE, secretKey);
  140. return cipher.doFinal(data);
  141. } catch (Exception exception) {
  142. String message = StringUtility.format("AES解密数据异常:[{}]", Arrays.toString(data));
  143. throw new RuntimeException(message, exception);
  144. }
  145. }
  146. /**
  147. * Blowfish加密
  148. *
  149. * @param data
  150. * @param key
  151. * @return
  152. */
  153. public static byte[] encryptBlowfish(final byte[] data, final byte[] key) {
  154. try {
  155. SecretKeySpec secretKey = new SecretKeySpec(key, Blowfish);
  156. Cipher cipher = Cipher.getInstance(Blowfish);
  157. cipher.init(Cipher.ENCRYPT_MODE, secretKey);
  158. return cipher.doFinal(data);
  159. } catch (Exception exception) {
  160. String message = StringUtility.format("Blowfish加密数据异常:[{}]", Arrays.toString(data));
  161. throw new RuntimeException(message, exception);
  162. }
  163. }
  164. /**
  165. * Blowfish解密
  166. *
  167. * @param data
  168. * @param key
  169. * @return
  170. */
  171. public static byte[] decryptBlowfish(final byte[] data, final byte[] key) {
  172. try {
  173. SecretKeySpec secretKey = new SecretKeySpec(key, Blowfish);
  174. Cipher cipher = Cipher.getInstance(Blowfish);
  175. cipher.init(Cipher.DECRYPT_MODE, secretKey);
  176. return cipher.doFinal(data);
  177. } catch (Exception exception) {
  178. String message = StringUtility.format("Blowfish解密数据异常:[{}]", Arrays.toString(data));
  179. throw new RuntimeException(message, exception);
  180. }
  181. }
  182. /**
  183. * DES加密
  184. *
  185. * @param data
  186. * @param key
  187. * @return
  188. */
  189. public static byte[] encryptDes(byte[] data, byte[] key) {
  190. try {
  191. // DES算法要求有一个可信任的随机数源
  192. SecureRandom random = new SecureRandom();
  193. DESKeySpec desKey = new DESKeySpec(key);
  194. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
  195. SecretKey secretKey = keyFactory.generateSecret(desKey);
  196. Cipher cipher = Cipher.getInstance(DES);
  197. cipher.init(Cipher.ENCRYPT_MODE, secretKey, random);
  198. return cipher.doFinal(data);
  199. } catch (Exception exception) {
  200. String message = StringUtility.format("DES加密数据异常:[{}]", Arrays.toString(data));
  201. throw new RuntimeException(message, exception);
  202. }
  203. }
  204. /**
  205. * DES解密
  206. *
  207. * @param data
  208. * @param key
  209. * @return
  210. */
  211. public static byte[] decryptDes(byte[] data, byte[] key) {
  212. try {
  213. // DES算法要求有一个可信任的随机数源
  214. SecureRandom random = new SecureRandom();
  215. DESKeySpec desKey = new DESKeySpec(key);
  216. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(DES);
  217. SecretKey secretKey = keyFactory.generateSecret(desKey);
  218. Cipher cipher = Cipher.getInstance(DES);
  219. cipher.init(Cipher.DECRYPT_MODE, secretKey, random);
  220. return cipher.doFinal(data);
  221. } catch (Exception exception) {
  222. String message = StringUtility.format("DES解密数据异常:[{}]", Arrays.toString(data));
  223. throw new RuntimeException(message, exception);
  224. }
  225. }
  226. /**
  227. * 获取RSA非对称秘钥
  228. *
  229. * @param size
  230. * @return
  231. */
  232. public static KeyValue<byte[], byte[]> getRsa(int size) {
  233. try {
  234. KeyPairGenerator rsa = KeyPairGenerator.getInstance(RSA);
  235. SecureRandom random = new SecureRandom();
  236. rsa.initialize(size, random);
  237. KeyPair keys = rsa.generateKeyPair();
  238. return new KeyValue<>(keys.getPrivate().getEncoded(), keys.getPublic().getEncoded());
  239. } catch (Exception exception) {
  240. String message = StringUtility.format("获取RAS密匙异常:[{}]");
  241. throw new RuntimeException(message, exception);
  242. }
  243. }
  244. /**
  245. * RSA加密
  246. *
  247. * @param data
  248. * @param key
  249. * @return
  250. */
  251. public static byte[] encryptRsa(final byte[] data, final byte[] key) {
  252. try {
  253. X509EncodedKeySpec secretKey = new X509EncodedKeySpec(key);
  254. KeyFactory keyFactory = KeyFactory.getInstance(RSA);
  255. PublicKey publicKey = keyFactory.generatePublic(secretKey);
  256. Cipher cipher = Cipher.getInstance(RSA);
  257. cipher.init(Cipher.ENCRYPT_MODE, publicKey);
  258. return cipher.doFinal(data);
  259. } catch (Exception exception) {
  260. String message = StringUtility.format("RSA加密数据异常:[{}]", Arrays.toString(data));
  261. throw new RuntimeException(message, exception);
  262. }
  263. }
  264. /**
  265. * RSA解密
  266. *
  267. * @param data
  268. * @param key
  269. * @return
  270. */
  271. public static byte[] decryptRsa(final byte[] data, final byte[] key) {
  272. try {
  273. PKCS8EncodedKeySpec secretKey = new PKCS8EncodedKeySpec(key);
  274. KeyFactory keyFactory = KeyFactory.getInstance(RSA);
  275. PrivateKey privateKey = keyFactory.generatePrivate(secretKey);
  276. Cipher cipher = Cipher.getInstance(RSA);
  277. cipher.init(Cipher.DECRYPT_MODE, privateKey);
  278. return cipher.doFinal(data);
  279. } catch (Exception exception) {
  280. String message = StringUtility.format("RSA解密数据异常:[{}]", Arrays.toString(data));
  281. throw new RuntimeException(message, exception);
  282. }
  283. }
  284. /**
  285. * MD5摘要
  286. *
  287. * <pre>
  288. * http://www.atool.org/hash.php
  289. * </pre>
  290. *
  291. * @param data
  292. * @return
  293. */
  294. public static byte[] signatureMd5(byte[] data) {
  295. try {
  296. MessageDigest algorithm = MessageDigest.getInstance(MD5);
  297. return algorithm.digest(data);
  298. } catch (Exception exception) {
  299. String message = StringUtility.format("[{}]:MD5信息摘要异常", data);
  300. throw new RuntimeException(message, exception);
  301. }
  302. }
  303. /**
  304. * SHA1摘要
  305. *
  306. * <pre>
  307. * http://www.atool.org/hash.php
  308. * </pre>
  309. *
  310. * @param data
  311. * @return
  312. */
  313. public static byte[] signatureSha1(byte[] data) {
  314. try {
  315. MessageDigest algorithm = MessageDigest.getInstance(SHA1);
  316. return algorithm.digest(data);
  317. } catch (Exception exception) {
  318. String message = StringUtility.format("[{}]:SHA1信息摘要异常", data);
  319. throw new RuntimeException(message, exception);
  320. }
  321. }
  322. /**
  323. * SHA224摘要
  324. *
  325. * @param data
  326. * @return
  327. */
  328. public static byte[] signatureSha224(byte[] data) {
  329. try {
  330. MessageDigest algorithm = MessageDigest.getInstance(SHA224);
  331. return algorithm.digest(data);
  332. } catch (Exception exception) {
  333. String message = StringUtility.format("[{}]:SHA224信息摘要异常", data);
  334. throw new RuntimeException(message, exception);
  335. }
  336. }
  337. /**
  338. * SHA256摘要
  339. *
  340. * <pre>
  341. * http://www.atool.org/hash.php
  342. * </pre>
  343. *
  344. * @param data
  345. * @return
  346. */
  347. public static byte[] signatureSha256(byte[] data) {
  348. try {
  349. MessageDigest algorithm = MessageDigest.getInstance(SHA256);
  350. return algorithm.digest(data);
  351. } catch (Exception exception) {
  352. String message = StringUtility.format("[{}]:SHA256信息摘要异常", data);
  353. throw new RuntimeException(message, exception);
  354. }
  355. }
  356. /**
  357. * SHA384摘要
  358. *
  359. * @param data
  360. * @return
  361. */
  362. public static byte[] signatureSha384(byte[] data) {
  363. try {
  364. MessageDigest algorithm = MessageDigest.getInstance(SHA384);
  365. return algorithm.digest(data);
  366. } catch (Exception exception) {
  367. String message = StringUtility.format("[{}]:SHA384信息摘要异常", data);
  368. throw new RuntimeException(message, exception);
  369. }
  370. }
  371. /**
  372. * SHA512摘要
  373. *
  374. * <pre>
  375. * http://www.atool.org/hash.php
  376. * </pre>
  377. *
  378. * @param data
  379. * @return
  380. */
  381. public static byte[] signatureSha512(byte[] data) {
  382. try {
  383. MessageDigest algorithm = MessageDigest.getInstance(SHA512);
  384. return algorithm.digest(data);
  385. } catch (Exception exception) {
  386. String message = StringUtility.format("[{}]:SHA512信息摘要异常", data);
  387. throw new RuntimeException(message, exception);
  388. }
  389. }
  390. }