当前位置:   article > 正文

DES、AES加密、MD5、SHA256等散列生成(java代码)_secretkey iv生成器

secretkey iv生成器

目录

■前言

■代码

■运行效果

■其它

・Access restriction. (访问限制)

・MD5、SHA-256 等  MessageDigest  算法 ,生成 Hash序列

■DES介绍

■DES的Java代码

■DES 和 AES 的区别

■AES 坑 :【InvalidKeyException】

■加密解密的简易代码


===

■前言

WebAPI直接,HTTP传送数据,数据加密

■代码

注意,加密之后,使用Base64转换位字符串,方便传输。

  1. package com.sxz.study.aes;
  2. import java.math.BigInteger;
  3. import java.nio.charset.Charset;
  4. import java.nio.charset.StandardCharsets;
  5. import java.security.SecureRandom;
  6. import java.util.Base64;
  7. import javax.crypto.Cipher;
  8. import javax.crypto.KeyGenerator;
  9. import javax.crypto.SecretKey;
  10. import javax.crypto.spec.IvParameterSpec;
  11. public class TestAES {
  12. public static void main(String[] args) {
  13. String encodeStr;
  14. String decodeStr;
  15. try {
  16. encodeStr = AESEncode("123encodeKey", "中国大连-2023年3月14日");
  17. System.out.println(encodeStr);
  18. decodeStr = AESDecode("123encodeKey", encodeStr);
  19. System.out.println(decodeStr);
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. }
  23. System.out.println("大連".getBytes(StandardCharsets.UTF_8).length);
  24. System.out.println("大連".getBytes(Charset.forName("MS932")).length);
  25. System.out.println("大連".getBytes(Charset.forName("GBK")).length);
  26. System.out.println("大連".getBytes(Charset.forName("UTF8")).length);
  27. System.out.println("大連".getBytes(Charset.forName("UTF-8")).length);
  28. }
  29. /**
  30. * 加密
  31. * 1.构造密钥生成器
  32. * 2.根据ecnodeRules规则初始化密钥生成器
  33. * 3.产生密钥
  34. * 4.创建和初始化密码器
  35. * 5.内容加密
  36. * 6.返回字符串
  37. */
  38. public static String AESEncode(String encodeRules, String content) throws Exception {
  39. // 1.构造密钥生成器,指定为AES算法,不区分大小写
  40. KeyGenerator keygen = KeyGenerator.getInstance("AES");
  41. // 2.根据ecnodeRules规则初始化密钥生成器
  42. // 生成一个128位的随机源,根据传入的字节数组
  43. keygen.init(128, new SecureRandom(encodeRules.getBytes()));
  44. // 3.产生原始对称密钥
  45. SecretKey originalKey = keygen.generateKey();
  46. // 3'.另外一种生成Key的方法
  47. // byte[] bytes32 = "123456789012345678901234567890AB".getBytes();
  48. // SecretKey originalKey = new SecretKeySpec(bytes32,"AES");
  49. // --------- 加密 KEY 確認 用代碼 ------- 【START】
  50. BigInteger bi = null;
  51. bi = new BigInteger(1, originalKey.getEncoded());
  52. String keyHexStr = bi.toString(16);
  53. String md5StrFormat = String.format("%32s", keyHexStr); // 不足32位,前面补空格
  54. keyHexStr = md5StrFormat.replace(" ", "0"); // 把空格替换成0
  55. System.out.println(bytesToBin(originalKey.getEncoded()));
  56. System.out.println("---AES_KEY--- bigInt :" + bi);
  57. System.out.println("---AES_KEY--- 16进制 :" + keyHexStr);
  58. System.out.println("---AES_KEY--- 16进制 长度:" + keyHexStr.length());
  59. System.out.println("---AES_KEY--- 2进制 长度:" + keyHexStr.length()*4);
  60. // --------- 加密 KEY 確認 用代碼 ------- 【 END 】
  61. // // 4.获得原始对称密钥的字节数组
  62. // byte[] raw = originalKey.getEncoded();
  63. // // 5.根据字节数组生成AES密钥
  64. // SecretKey key = new SecretKeySpec(raw, "AES");
  65. // 6.根据指定算法AES自成密码器 【★★★ 这里才是真正的ASE加密相关的代码!】
  66. // Cipher cipher = Cipher.getInstance("AES");
  67. // 算法:AES
  68. // 加密模式:ECB (默认)
  69. // 如果需要使用CBC模式,则需要加入额外的IV参数。
  70. // 填充模式:pkcs5padding(默认)
  71. Cipher cipher = Cipher.getInstance("AES/ECB/pkcs5padding"); // 算法/模式/补码方式
  72. // =============================================================================================
  73. // 【加密模式】
  74. // AES五种加密模式(ECB、CBC、CTR、OCF、CFB)
  75. // 块加密,常用的加密模式有ECB、CBC。
  76. // ECB,即electronic code book,
  77. // 将整个明文分成若干段相同小段,然后每小段进行加密,
  78. // 每段互不依赖,可以并行处理,同样的明文就会生成同样的密文;
  79. // CBC,即cipher block chaining,
  80. // 密文分组链模式,密文分组间如同链条相互连接,先将明文切割为若干段,
  81. // 每一小段与上一段的密文段运算后(第一个块没有上个密文段,故而使用IV进行运算),
  82. // 再同秘钥进行加密,因为是串行处理,所以同样明文每次生成的密文不一样。
  83. // 【填充模式】 (pkcs5padding)
  84. // 块加密中,常用还有填充模式,对于固定加密算法,每个块有固定大小,
  85. // 如AES的块大小为16个字节的整数倍,
  86. // 明文分块时,如果块大小不够,则需要使用固定数据进行填充。
  87. //
  88. // 【IV】(初始化向量)
  89. // AES的Cipher.getInstance调用时,使用AES即可,
  90. // 默认使用的分组模式就是ECB,填充模式为PKCS5Padding。
  91. // 如果需要使用CBC模式,则需要加入额外的Iv参数。
  92. // (ECB模式不需要 IV,强制使用会出错)
  93. // (java.security.InvalidAlgorithmParameterException: ECB mode cannot use IV)
  94. // =======================
  95. // String sIv = "1234567890123ABC";//16位自定义向量
  96. // byte[] bytes = sIv.getBytes();
  97. // IvParameterSpec iv = new IvParameterSpec(bytes);//使用CBC模式,需要一个向量iv,可增加加密算法的强度
  98. //
  99. // Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//"算法/模式/补码方式"
  100. // cipher.init(Cipher.ENCRYPT_MODE, originalKey, iv);
  101. // =======================
  102. // =============================================================================================
  103. // 7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
  104. cipher.init(Cipher.ENCRYPT_MODE, originalKey);
  105. // Cipher 英 [ˈsaɪfə] n. 密码 v. 使用密码,
  106. // cipher,通常指的是使用一种特殊的算法进行加密
  107. // 8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
  108. byte[] byteEncode = content.getBytes(StandardCharsets.UTF_8);
  109. // 9.根据密码器的初始化方式--加密:将数据加密
  110. byte[] aes = cipher.doFinal(byteEncode);
  111. // return Base64.encodeBase64String(aes);
  112. String AES_encode = Base64.getEncoder().encodeToString(aes);
  113. return AES_encode;
  114. }
  115. /**
  116. * 解密
  117. * 解密过程:
  118. * 1.同加密1-4步
  119. * 2.将加密后的字符串反纺成byte[]数组
  120. * 3.将加密内容解密
  121. */
  122. public static String AESDecode(String encodeRules, String content) throws Exception {
  123. // 1.构造密钥生成器,指定为AES算法,不区分大小写
  124. KeyGenerator keygen = KeyGenerator.getInstance("AES");
  125. // 2.根据ecnodeRules规则初始化密钥生成器
  126. // 生成一个128位的随机源,根据传入的字节数组
  127. keygen.init(128, new SecureRandom(encodeRules.getBytes()));
  128. // 3.产生原始对称密钥
  129. SecretKey originalKey = keygen.generateKey();
  130. // 3'.另外一种生成Key的方法
  131. // byte[] bytes32 = "123456789012345678901234567890AB".getBytes();
  132. // SecretKey originalKey = new SecretKeySpec(bytes32,"AES");
  133. // // 4.获得原始对称密钥的字节数组
  134. // byte[] raw = originalKey.getEncoded();
  135. // // 5.根据字节数组生成AES密钥
  136. // SecretKey key = new SecretKeySpec(raw, "AES");
  137. // 6.根据指定算法AES自成密码器
  138. Cipher cipher = Cipher.getInstance("AES");
  139. // 【IV】
  140. // =====================
  141. // String sIv = "1234567890123ABC";//16位自定义向量
  142. // byte[] bytes = sIv.getBytes();
  143. // IvParameterSpec iv = new IvParameterSpec(bytes);//使用CBC模式,需要一个向量iv,可增加加密算法的强度
  144. //
  145. // Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//"算法/模式/补码方式"
  146. // cipher.init(Cipher.DECRYPT_MODE, originalKey, iv);
  147. // =====================
  148. // 7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
  149. cipher.init(Cipher.DECRYPT_MODE, originalKey);
  150. // 7.5.获取加密字符串(Base64)的 字节数组
  151. // byte[] byteContent = Base64.decodeBase64(content); // 不再推荐使用的方法
  152. byte[] byteContent = Base64.getDecoder().decode(content);
  153. // 8.解码
  154. byte[] byteDecode = cipher.doFinal(byteContent);
  155. return new String(byteDecode, StandardCharsets.UTF_8);
  156. }
  157. /**
  158. * 把多个字节转换成二进制字符串
  159. */
  160. public static String bytesToBin(byte[] bytes) {
  161. StringBuffer sb = new StringBuffer();
  162. for (byte b : bytes) {
  163. String zero = "00000000";
  164. String binStr = Integer.toBinaryString(b & 0xFF);
  165. if(binStr.length() < 8) {
  166. binStr = zero.substring(0, 8 -binStr.length()) + binStr;
  167. }
  168. sb.append(binStr);
  169. }
  170. return sb.toString();
  171. }
  172. /**
  173. * 把单个字节转换成二进制字符串
  174. */
  175. public static String byteToBin(byte b) {
  176. String zero = "00000000";
  177. String binStr = Integer.toBinaryString(b & 0xFF);
  178. if(binStr.length() < 8) {
  179. binStr = zero.substring(0, 8 -binStr.length()) + binStr;
  180. }
  181. return binStr;
  182. }
  183. }

■运行效果

  1. 00100111011011011111110101111011100000101001010000101100000101001010001110101010110010010110011000001001101011000001100001001100
  2. ---AES_KEY--- bigInt :52410993428297908844820493916267354188
  3. ---AES_KEY--- 16进制 :276dfd7b82942c14a3aac96609ac184c
  4. ---AES_KEY--- 16进制 长度:32
  5. ---AES_KEY--- 2进制 长度:128
  6. Ux38V/CaQjMWSfyFP1Qmqnkk8oqwigUZuLR5Op2FBAI=
  7. 中国大连-2023314
  8. 6
  9. 4
  10. 4
  11. 6
  12. 6

===

■其它

・Access restriction. (访问限制)

从JDK1.8开始,SUN公司就已经建议不再使用 sun.misc.BASE64Encoder与sun.misc.BASE64Decoder了,推荐使用 java.util.Base64 工具类来将其替换.
使用sun.misc.BASE64时,会出现【Access restriction】 的警告。

(restriction 英 [rɪˈstrɪkʃən]  n. 限制;约束 )

  1. Multiple markers at this line
  2. - Access restriction: The constructor 'BASE64Encoder()' is not API (restriction on required library 'C:\java\8\8\jre\lib\rt.jar')
  3. - Access restriction: The method 'CharacterEncoder.encode(byte[])' is not API (restriction on required library 'C:\java\8\8\jre\lib\rt.jar')
  4. - Access restriction: The type 'BASE64Encoder' is not API (restriction on required library 'C:\java\8\8\jre\lib\rt.jar')

・MD5、SHA-256 等  MessageDigest  算法 ,生成 Hash序列

MD5 与 Base64一起使用 加密,计算原理_md5 base64_sun0322的博客-CSDN博客

---

  1. package com.sxz.study.messageDigest;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.IOException;
  5. import java.io.UnsupportedEncodingException;
  6. import java.math.BigInteger;
  7. import java.security.MessageDigest;
  8. import java.security.NoSuchAlgorithmException;
  9. public class MessageDigestTest {
  10. public static void main(String[] args) {
  11. String md5str1 = getMessageDigestByStr("5123", "MD5");
  12. System.out.println(md5str1);
  13. String md5str2 = getMessageDigestByStr("5123", "SHA-256");
  14. System.out.println(md5str2);
  15. String md5str3 = getMessageDigestByFile("C:\\test\\to\\sss.txt");
  16. System.out.println(md5str3);
  17. String md5str1_method2 = getMessageDigestByStr_method2("5123", "MD5");
  18. System.out.println(md5str1_method2);
  19. System.out.println(String.format("%32s", "5123")); // 不足32位,前面补空格
  20. String md5str1_bug_method = getMessageDigestByStrBugMethod("5123", "MD5");
  21. System.out.println(md5str1_bug_method);
  22. }
  23. public static String getMessageDigestByStr(String msgStr, String algorithmStr) {
  24. BigInteger bi = null;
  25. try {
  26. MessageDigest md = MessageDigest.getInstance(algorithmStr);
  27. byte[] buffer = md.digest(msgStr.getBytes("utf-8"));
  28. bi = new BigInteger(1, buffer);
  29. } catch (NoSuchAlgorithmException e) {
  30. e.printStackTrace();
  31. } catch (UnsupportedEncodingException e) {
  32. e.printStackTrace();
  33. }
  34. // 使用下面代码解决bug (PowerShell的值,有时会不相同) (MD5的值,是一个32位长度的字符串)
  35. String md5Str = bi.toString(16);
  36. // MD5の場合、 不足32位,前面补空格
  37. // SHA-256の場合、 不足64位,前面补空格
  38. String md5StrFormat = String.format("%32s", md5Str);
  39. String result = md5StrFormat.replace(" ", "0"); // 把空格替换成0
  40. return result.toUpperCase();
  41. }
  42. public static String getMessageDigestByFile(String filePath) {
  43. BigInteger bi = null;
  44. try {
  45. byte[] buffer = new byte[8192];
  46. int len = 0;
  47. MessageDigest md = MessageDigest.getInstance("MD5");
  48. File f = new File(filePath);
  49. FileInputStream fis = new FileInputStream(f);
  50. while ((len = fis.read(buffer)) != -1) {
  51. md.update(buffer, 0, len);
  52. }
  53. fis.close();
  54. byte[] b = md.digest();
  55. bi = new BigInteger(1, b);
  56. } catch (NoSuchAlgorithmException e) {
  57. e.printStackTrace();
  58. } catch (IOException e) {
  59. e.printStackTrace();
  60. }
  61. // 下面代码有BUG,当MD5的Hash值,第一位是0是,第一位会被省略。
  62. // return bi.toString(16);
  63. // 使用下面代码解决bug (MD5的值,是一个32位长度的字符串)
  64. String md5Str = bi.toString(16);
  65. String md5StrFormat = String.format("%32s", md5Str); // 不足32位,前面补空格
  66. String result = md5StrFormat.replace(" ", "0"); // 把空格替换成0
  67. return result.toUpperCase();
  68. }
  69. public static String getMessageDigestByStr_method2(String msgStr, String algorithmStr) {
  70. BigInteger bi = null;
  71. // 方法2
  72. byte[] buffer = null;
  73. try {
  74. MessageDigest md = MessageDigest.getInstance(algorithmStr);
  75. // 方法2
  76. buffer = md.digest(msgStr.getBytes("utf-8"));
  77. // 方法1
  78. // byte[] buffer = md.digest(msgStr.getBytes("utf-8"));
  79. // bi = new BigInteger(1, buffer);
  80. } catch (NoSuchAlgorithmException e) {
  81. e.printStackTrace();
  82. } catch (UnsupportedEncodingException e) {
  83. e.printStackTrace();
  84. }
  85. // 方法1
  86. // // 使用下面代码解决bug (PowerShell的值,有时会不相同) (MD5的值,是一个32位长度的字符串)
  87. // String md5Str = bi.toString(16);
  88. //
  89. // // MD5の場合、 不足32位,前面补空格
  90. // // SHA-256の場合、 不足64位,前面补空格
  91. // String md5StrFormat = String.format("%32s", md5Str);
  92. // String result = md5StrFormat.replace(" ", "0"); // 把空格替换成0
  93. //
  94. // return result.toUpperCase();
  95. // 方法2
  96. return hex(buffer);
  97. }
  98. public static String hex(byte[] bytes) {
  99. StringBuilder result = new StringBuilder();
  100. for (byte aByte : bytes) {
  101. result.append(String.format("%02x", aByte));
  102. // upper case
  103. // result.append(String.format("%02X", aByte));
  104. }
  105. return result.toString();
  106. }
  107. public static String getMessageDigestByStrBugMethod(String msgStr, String algorithmStr) {
  108. BigInteger bi = null;
  109. try {
  110. MessageDigest md = MessageDigest.getInstance(algorithmStr);
  111. byte[] buffer = md.digest(msgStr.getBytes("utf-8"));
  112. bi = new BigInteger(1, buffer);
  113. } catch (NoSuchAlgorithmException e) {
  114. e.printStackTrace();
  115. } catch (UnsupportedEncodingException e) {
  116. e.printStackTrace();
  117. }
  118. // 使用下面代码解决bug (PowerShell的值,有时会不相同) (MD5的值,是一个32位长度的字符串)
  119. String md5Str = bi.toString(16);
  120. // // MD5の場合、 不足32位,前面补空格
  121. // // SHA-256の場合、 不足64位,前面补空格
  122. // String md5StrFormat = String.format("%32s", md5Str);
  123. // String result = md5StrFormat.replace(" ", "0"); // 把空格替换成0
  124. //
  125. // return result.toUpperCase();
  126. //
  127. return md5Str;
  128. }
  129. }

===

結果

  1. 037A595E6F4F0576A9EFE43154D71C18
  2. 4F9EB48D371E25B05D5DF80EEBB343C6BFB067D274301DB24DD26D26E8AEB6AB
  3. 037A595E6F4F0576A9EFE43154D71C18
  4. 037a595e6f4f0576a9efe43154d71c18
  5. 5123
  6. 37a595e6f4f0576a9efe43154d71c18

===

■DES介绍

"DES"是Data Encryption Standard(数据加密标准)的缩写。DES是一种对称加密算法,它使用相同的密钥来加密和解密数据。DES算法最早在1977年被美国国家标准技术研究所(NIST)采纳为联邦标准,但现在已经被更安全的算法替代。

DES使用56位密钥,将64位的明文输入划分成16个56位的子块,然后对每个子块执行一系列的复杂混合和替换操作。它的目的是将明文转换为随机的密文,以保护数据的机密性。

尽管DES在过去几十年间被广泛使用,但由于56位密钥空间较小,容易受到攻击,因此现在已经被更安全的加密算法(如AES)所取代。

xxx

==

■DES的Java代码

该示例使用了Java加密库中的Cipher类和SecretKeyFactory类来实现DES加密。在encrypt方法中,首先使用密钥生成DESKeySpec对象,然后使用SecretKeyFactory生成SecretKey对象。接下来,通过Cipher类的init方法指定加密模式和密钥,然后通过调用doFinal方法对明文进行加密。在decrypt方法中,步骤与加密相似,只是将加密模式设置为解密模式,并对密文进行解密操作。

请注意,由于DES算法已经很旧且不够安全,不建议在实际应用中使用。

==

  1. import javax.crypto.Cipher;
  2. import javax.crypto.SecretKey;
  3. import javax.crypto.SecretKeyFactory;
  4. import javax.crypto.spec.DESKeySpec;
  5. import java.nio.charset.StandardCharsets;
  6. import java.util.Base64;
  7. public class DESExample {
  8. public static void main(String[] args) throws Exception {
  9. String plainText = "This is the message to be encrypted";
  10. String key = "ThisIsKey";
  11. byte[] encryptedText = encrypt(plainText, key);
  12. System.out.println("Encrypted Text: " + Base64.getEncoder().encodeToString(encryptedText));
  13. String decryptedText = decrypt(encryptedText, key);
  14. System.out.println("Decrypted Text: " + decryptedText);
  15. }
  16. public static byte[] encrypt(String plainText, String key) throws Exception {
  17. DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
  18. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
  19. SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
  20. Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
  21. cipher.init(Cipher.ENCRYPT_MODE, secretKey);
  22. return cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
  23. }
  24. public static String decrypt(byte[] encryptedText, String key) throws Exception {
  25. DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
  26. SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
  27. SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
  28. Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
  29. cipher.init(Cipher.DECRYPT_MODE, secretKey);
  30. byte[] decryptedBytes = cipher.doFinal(encryptedText);
  31. return new String(decryptedBytes, StandardCharsets.UTF_8);
  32. }
  33. }

===

■DES 和 AES 的区别

DES(Data Encryption Standard)和AES(Advanced Encryption Standard)是两种对称加密算法,它们在加密和解密过程中使用相同的密钥。

主要区别如下:

  1. 密钥长度:DES使用56位密钥,而AES可以使用128位、192位或256位密钥。AES密钥长度更长,提供更高的安全性。

  2. 安全性:由于DES密钥空间较小,容易受到穷举攻击(遍历所有可能的密钥值)和差分分析等攻击。相比之下,AES具有更大且更复杂的密钥空间,更难以被破解。

  3. 密码分组长度:DES将64位明文分为16个56位子块,每个子块进行加密操作。而AES将明文分为128位块,并在加密过程中对整个块进行操作。

  4. 应用领域:DES较为适用于早期的应用,如金融交易和电子邮件加密。而AES被广泛认可为目前最安全和最常用的加密算法,用于保护敏感信息,如数据库、云存储和网络通信等领域。

总结来说,AES比DES更安全和高效,因此在现代加密应用中,AES是首选的对称加密算法。

xxx

===

■AES 坑 :【InvalidKeyException】

========================

1. 项目使用AES加密,出现异常如下:
java.security.InvalidKeyException: Illegal key size

2. 为解决“AES的256位密钥加解密报 java.security.InvalidKeyException: Illegal key size or default parameters 异常”问题:
需要使用oracle提供的无政策限制权限文件,在oracle官网上下载JDK对应版本的JCE文件,替换jre1.x\lib\security下面的local_policy.jar和
US_export_policy.jar两个文件。

异常原因:如果密钥大于128, 会抛出java.security.InvalidKeyException: Illegal key size 异常. 因为密钥长度是受限制的, java运行时环境读到的是受限的policy文件. 文件位于${java_home}/jre/lib/security, 这种限制是因为美国对软件出口的控制.

不过,一般的JDK中的JRE中的Jar,不存在以上这个问题

====

====

■加密解密的简易代码

===

  1. package com.sxz.study.aes;
  2. import java.util.Base64;
  3. import javax.crypto.Cipher;
  4. import javax.crypto.SecretKey;
  5. import javax.crypto.spec.IvParameterSpec;
  6. import javax.crypto.spec.SecretKeySpec;
  7. public class AESUTil {
  8. public static void main(String[] args) {
  9. String content = "大连";
  10. String seretKeyStr = "aabbCCdrewrwyda1235rwetrwadfafdsfABCewrwerO="; // 44
  11. String ivStr = "abcdefgh123456AB"; // 16
  12. String encodeStr = encodeByAES(content,seretKeyStr,ivStr);
  13. System.out.println(encodeStr);
  14. String decodeStr = decodeByAES(encodeStr,seretKeyStr,ivStr);
  15. System.out.println(decodeStr);
  16. }
  17. public static String encodeByAES(String content, String seretKeyStr, String ivStr) {
  18. String contentEncode = "";
  19. byte by[] = Base64.getDecoder().decode(seretKeyStr); // length:44*(6/8)= 33; 32 *8=256bit
  20. SecretKey secretKey = new SecretKeySpec(by, "AES");
  21. try {
  22. Cipher cipher = Cipher.getInstance("AES/CBC/pkcs5padding");
  23. IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
  24. cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
  25. byte[] encryptData = cipher.doFinal(content.getBytes("UTF-8"));
  26. contentEncode = Base64.getEncoder().encodeToString(encryptData);
  27. } catch (Exception e) {
  28. e.printStackTrace();
  29. }
  30. return contentEncode;
  31. }
  32. public static String decodeByAES(String content, String seretKeyStr, String ivStr) {
  33. String contentDecode = "";
  34. byte by[] = Base64.getDecoder().decode(seretKeyStr);
  35. SecretKey secretKey = new SecretKeySpec(by, "AES");
  36. try {
  37. Cipher cipher = Cipher.getInstance("AES/CBC/pkcs5padding");
  38. IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
  39. cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
  40. byte[] decodeBase64 = Base64.getDecoder().decode(content);
  41. byte[] decode = cipher.doFinal(decodeBase64);
  42. contentDecode = new String (decode, "UTF-8");
  43. } catch (Exception e) {
  44. e.printStackTrace();
  45. }
  46. return contentDecode;
  47. }
  48. }

 ========================

irGJLXmvOa6NJWTlMBWxzQ==
大连

・base64编码

Base64编码_base64区分大小写吗-CSDN博客

・base64编码后面的=

(为什么 // length:44*(6/8)= 33; 32 *8=256bit)

base64编码后面数据存在“=”或“==”是因为编码数据二进制转化后,按照Base64规则进行编码不够而进行补得位,缺一位就补一个“=”,缺两位就补两个“=”;

如果需要表示上面的64个字符,那么需要6bit,也就是2^6=64,base64的核心思想就是,

将3个字节拆分成4个6bit,然后对每个6bit的高位补2个0,构成1个字节。

也即是每3个字节最终结果将变成4个字节。

如果原始字符串的字节数不是3的整数倍,那么就用0来填充,用来填充的0就被编码成了'=',这就是出现=的原因,并且只会出现在结果出,如果原始字符刚好是3字节的整数倍,那么就没有等号了。

======

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/43869
推荐阅读
相关标签
  

闽ICP备14008679号