Java 實現一個AES/ECB/PKCS5Padding
加解密算法工具類java
<!-- more -->git
import lombok.Getter; import lombok.Setter; import lombok.extern.slf4j.Slf4j; import org.springframework.util.Base64Utils; import javax.crypto.Cipher; import javax.crypto.spec.SecretKeySpec; import java.io.BufferedInputStream; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; /** * Created by @author yihui in 19:12 20/1/2. */ @Slf4j public class EncryptUtil { private static final String KEY_ALGORITHM = "AES"; /** * 算法/模式/補碼方式 */ private static final String DEFAULT_CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding"; private static final String CODE = "utf-8"; @Setter @Getter public static String encryptKey; public static String encrypt(String content) { return encrypt(content, encryptKey); } /** * 加密 * * @param content * @param key * @return * @throws Exception */ public static String encrypt(String content, String key) { try { byte[] encrypted = encrypt2bytes(content, key); return Base64Utils.encodeToString(encrypted); } catch (Exception e) { log.error("failed to encrypt: {} of {}", content, e); return null; } } public static byte[] encrypt2bytes(String content, String key) { try { byte[] raw = key.getBytes(CODE); SecretKeySpec secretKeySpec = new SecretKeySpec(raw, KEY_ALGORITHM); Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec); return cipher.doFinal(content.getBytes(CODE)); } catch (Exception e) { log.error("failed to encrypt: {} of {}", content, e); return null; } } public static String decrypt(String content) { try { return decrypt(content, encryptKey); } catch (Exception e) { log.error("failed to decrypt: {}, e: {}", content, e); return null; } } /** * 解密 * * @param content * @param key * @return * @throws Exception */ public static String decrypt(String content, String key) throws Exception { return decrypt(Base64Utils.decodeFromString(content), key); } public static String decrypt(byte[] content, String key) throws Exception { if (key == null) { log.error("AES key should not be null"); return null; } byte[] raw = key.getBytes(CODE); SecretKeySpec keySpec = new SecretKeySpec(raw, KEY_ALGORITHM); Cipher cipher = Cipher.getInstance(DEFAULT_CIPHER_ALGORITHM); cipher.init(Cipher.DECRYPT_MODE, keySpec); try { byte[] original = cipher.doFinal(content); return new String(original, CqODE); } catch (Exception e) { log.error("failed to decrypt content: {}/ key: {}, e: {}", content, key, e); return null; } } }
請注意上面的實現,提供了兩種方式github
咱們提供了兩個加密的文件,用於解密使用;算法
base64加解密spring
@Test public void testEncrypt() throws Exception { String abc = "Hello, 一灰灰Blog!"; String key = "JC66fRd3wj85k8Hr"; String out = EncryptUtil.encrypt(abc, key); System.out.println(out); System.out.println(EncryptUtil.decrypt(out, key)); }
輸出結果如:數組
TKrN7VKrqsAQ4JqygeHOlG21Sd3IRJ3Y11k4kOdOG4s= Hello, 一灰灰Blog!
字節數組加解密工具
@Test public void testEncryptByte() throws Exception { String abc = "Hello, 一灰灰Blog!"; String key = "JC66fRd3wj85k8Hr"; byte[] out = EncryptUtil.encrypt2bytes(abc, key); System.out.println(new String(out)); System.out.println(EncryptUtil.decrypt(out, key)); }
輸出結果如:學習
// 加密的字節數組,就是亂碼... 你沒看錯 L���R��������Δm�I��D���Y8��N� Hello, 一灰灰Blog!
爲何有上面兩種區別?測試
若是咱們將加密後的字節數組,直接 new String()
得到一個字符串,而後解密這個字符串,會發現解密失敗哦ui
簡單修改一下上面的測試用例
@Test public void testEncryptByte() throws Exception { String abc = "Hello, 一灰灰Blog!"; String key = "JC66fRd3wj85k8Hr"; byte[] out = EncryptUtil.encrypt2bytes(abc, key); String enc = new String(out, "utf-8"); System.out.println(enc); System.out.println(EncryptUtil.decrypt(enc.getBytes("utf-8"), key)); }
執行以後,發現解密失敗
爲啥會出現這樣狀況呢?
enc = new String(out, "utf-8")
與 enc.getBytes("utf-8")
字節數組轉字符串; 字符串轉字節數組這兩個過程會致使最終生成的字節數組,與原始的不一致!!!解密遠程資源的case
最後給一個解密遠程加密的二進制文件的實例case
private void binKey(String uri, String key) throws Exception { // 這個文件是沒有base64編碼,直接上傳的二進制 URL url = new URL(uri); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); InputStream stream = connection.getInputStream(); int lenth = connection.getContentLength(); byte[] out = new byte[lenth]; stream.read(out); stream.close(); String ans = decrypt(out, key); System.out.println(ans); } public void testDe() throws Exception { String key = "5JRHMJn8xHnMDRXa"; binKey("http://q8rnsprw0.bkt.clouddn.com/mwzz/b0001", key); }
一灰灰的我的博客,記錄全部學習和工做中的博文,歡迎你們前去逛逛
盡信書則不如,以上內容,純屬一家之言,因我的能力有限,不免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激
一灰灰blog