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

目录

■前言

■代码

■运行效果

■其它

・Access restriction. (访问限制)

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

■DES介绍

■DES的Java代码

■DES 和 AES 的区别

■AES 坑 :【InvalidKeyException】

■加密解密的简易代码


===

■前言

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

■代码

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

package com.sxz.study.aes;
 
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
 
public class TestAES {
 
	public static void main(String[] args) {
		
		String encodeStr;
		String decodeStr;
		try {
			encodeStr = AESEncode("123encodeKey", "中国大连-2023年3月14日");
			System.out.println(encodeStr);	
 
			decodeStr = AESDecode("123encodeKey", encodeStr);
			System.out.println(decodeStr);	
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	   System.out.println("大連".getBytes(StandardCharsets.UTF_8).length);	
	   System.out.println("大連".getBytes(Charset.forName("MS932")).length);	
	   System.out.println("大連".getBytes(Charset.forName("GBK")).length);
	   System.out.println("大連".getBytes(Charset.forName("UTF8")).length);	
	   System.out.println("大連".getBytes(Charset.forName("UTF-8")).length);
	
	   
	}
	
    /**
     * 加密
     * 1.构造密钥生成器
     * 2.根据ecnodeRules规则初始化密钥生成器
     * 3.产生密钥
     * 4.创建和初始化密码器
     * 5.内容加密
     * 6.返回字符串
     */
    public static String AESEncode(String encodeRules, String content) throws Exception {
 
		// 1.构造密钥生成器,指定为AES算法,不区分大小写 
		KeyGenerator keygen = KeyGenerator.getInstance("AES");
		// 2.根据ecnodeRules规则初始化密钥生成器
		// 生成一个128位的随机源,根据传入的字节数组
		keygen.init(128, new SecureRandom(encodeRules.getBytes()));
		// 3.产生原始对称密钥
		SecretKey originalKey = keygen.generateKey();

		// 3'.另外一种生成Key的方法
//		byte[] bytes32 = "123456789012345678901234567890AB".getBytes();
//		SecretKey originalKey = new SecretKeySpec(bytes32,"AES");
		
		// --------- 加密 KEY 確認 用代碼  ------- 【START】
		BigInteger bi = null;
		bi = new BigInteger(1, originalKey.getEncoded());
		String keyHexStr = bi.toString(16);
		String md5StrFormat = String.format("%32s", keyHexStr); // 不足32位,前面补空格
		keyHexStr = md5StrFormat.replace(" ", "0"); // 把空格替换成0
 
		System.out.println(bytesToBin(originalKey.getEncoded()));
		System.out.println("---AES_KEY---  bigInt :" + bi);
		System.out.println("---AES_KEY---  16进制  :" + keyHexStr);
		System.out.println("---AES_KEY---  16进制  长度:" + keyHexStr.length());
		System.out.println("---AES_KEY---   2进制 长度:" + keyHexStr.length()*4);
		// --------- 加密 KEY 確認 用代碼  ------- 【 END 】
		
//		// 4.获得原始对称密钥的字节数组
//		byte[] raw = originalKey.getEncoded();
//		// 5.根据字节数组生成AES密钥
//		SecretKey key = new SecretKeySpec(raw, "AES");
		
		// 6.根据指定算法AES自成密码器  【★★★ 这里才是真正的ASE加密相关的代码!】
//		Cipher cipher = Cipher.getInstance("AES");
		// 算法:AES
		// 加密模式:ECB    (默认)
		          // 如果需要使用CBC模式,则需要加入额外的IV参数。
		// 填充模式:pkcs5padding(默认)
		Cipher cipher = Cipher.getInstance("AES/ECB/pkcs5padding");  // 算法/模式/补码方式
// =============================================================================================
//				【加密模式】
//                AES五种加密模式(ECB、CBC、CTR、OCF、CFB)
//					块加密,常用的加密模式有ECB、CBC。
//						ECB,即electronic code book,
//						            将整个明文分成若干段相同小段,然后每小段进行加密,
//						            每段互不依赖,可以并行处理,同样的明文就会生成同样的密文;
//						CBC,即cipher block chaining,
//						             密文分组链模式,密文分组间如同链条相互连接,先将明文切割为若干段,
//						             每一小段与上一段的密文段运算后(第一个块没有上个密文段,故而使用IV进行运算),
//						             再同秘钥进行加密,因为是串行处理,所以同样明文每次生成的密文不一样。	
		
//				【填充模式】 (pkcs5padding)
//				         块加密中,常用还有填充模式,对于固定加密算法,每个块有固定大小,
//				         如AES的块大小为16个字节的整数倍,
//				        明文分块时,如果块大小不够,则需要使用固定数据进行填充。
//		
//				【IV】(初始化向量)
//				     AES的Cipher.getInstance调用时,使用AES即可,
//				         默认使用的分组模式就是ECB,填充模式为PKCS5Padding。
//				         如果需要使用CBC模式,则需要加入额外的Iv参数。
//				             (ECB模式不需要 IV,强制使用会出错)
//				             (java.security.InvalidAlgorithmParameterException: ECB mode cannot use IV)
//      =======================
//		String sIv = "1234567890123ABC";//16位自定义向量
//        byte[] bytes = sIv.getBytes();
//	    IvParameterSpec iv = new IvParameterSpec(bytes);//使用CBC模式,需要一个向量iv,可增加加密算法的强度
//	    
//		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//"算法/模式/补码方式"
//	    cipher.init(Cipher.ENCRYPT_MODE, originalKey, iv);
//      =======================
// =============================================================================================

		// 7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作,第二个参数为使用的KEY
		 cipher.init(Cipher.ENCRYPT_MODE, originalKey);
		
		
		// Cipher 英 [ˈsaɪfə]  n. 密码 v. 使用密码, 
		     // cipher,通常指的是使用一种特殊的算法进行加密
		
		
		// 8.获取加密内容的字节数组(这里要设置为utf-8)不然内容中如果有中文和英文混合中文就会解密为乱码
		byte[] byteEncode = content.getBytes(StandardCharsets.UTF_8);
		// 9.根据密码器的初始化方式--加密:将数据加密
		byte[] aes = cipher.doFinal(byteEncode);
 
		// return Base64.encodeBase64String(aes);
		String AES_encode = Base64.getEncoder().encodeToString(aes);
		return AES_encode;
        
    }
 
    /**
     * 解密
     * 解密过程:
     * 1.同加密1-4步
     * 2.将加密后的字符串反纺成byte[]数组
     * 3.将加密内容解密
     */
    public static String AESDecode(String encodeRules, String content) throws Exception {
 
		// 1.构造密钥生成器,指定为AES算法,不区分大小写
		KeyGenerator keygen = KeyGenerator.getInstance("AES");
		// 2.根据ecnodeRules规则初始化密钥生成器
		//   生成一个128位的随机源,根据传入的字节数组
		keygen.init(128, new SecureRandom(encodeRules.getBytes()));
		// 3.产生原始对称密钥
		SecretKey originalKey = keygen.generateKey();
		
		// 3'.另外一种生成Key的方法
//		byte[] bytes32 = "123456789012345678901234567890AB".getBytes();
//		SecretKey originalKey = new SecretKeySpec(bytes32,"AES");

//		// 4.获得原始对称密钥的字节数组
//		byte[] raw = originalKey.getEncoded();
//		// 5.根据字节数组生成AES密钥
//		SecretKey key = new SecretKeySpec(raw, "AES");
		
		
		// 6.根据指定算法AES自成密码器
		Cipher cipher = Cipher.getInstance("AES");
		
//		【IV】
//      =====================
//		String sIv = "1234567890123ABC";//16位自定义向量
//        byte[] bytes = sIv.getBytes();
//	    IvParameterSpec iv = new IvParameterSpec(bytes);//使用CBC模式,需要一个向量iv,可增加加密算法的强度
//	    
//		Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");//"算法/模式/补码方式"
//	    cipher.init(Cipher.DECRYPT_MODE, originalKey, iv);
//      =====================
		// 7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密(Decrypt_mode)操作,第二个参数为使用的KEY
		cipher.init(Cipher.DECRYPT_MODE, originalKey);

		// 7.5.获取加密字符串(Base64)的  字节数组
		// byte[] byteContent = Base64.decodeBase64(content); // 不再推荐使用的方法
		byte[] byteContent = Base64.getDecoder().decode(content);
		
		// 8.解码
		byte[] byteDecode = cipher.doFinal(byteContent);
		return new String(byteDecode, StandardCharsets.UTF_8);
 
    }
    
    
	/**
	 * 把多个字节转换成二进制字符串
	 */
	public static String bytesToBin(byte[] bytes) {
		
		StringBuffer sb = new StringBuffer();
		
		for (byte b : bytes) {
		
		
		String zero = "00000000";
		String binStr = Integer.toBinaryString(b & 0xFF);
		if(binStr.length() < 8) {
			binStr = zero.substring(0, 8 -binStr.length()) + binStr;
		}
		sb.append(binStr);
		
		}
		
		return sb.toString();
	}
 
    
	/**
	 * 把单个字节转换成二进制字符串
	 */
	public static String byteToBin(byte b) {
		String zero = "00000000";
		String binStr = Integer.toBinaryString(b & 0xFF);
		if(binStr.length() < 8) {
			binStr = zero.substring(0, 8 -binStr.length()) + binStr;
		}
		return binStr;
	}
 
 
}

■运行效果

00100111011011011111110101111011100000101001010000101100000101001010001110101010110010010110011000001001101011000001100001001100
---AES_KEY---  bigInt :52410993428297908844820493916267354188
---AES_KEY---  16进制  :276dfd7b82942c14a3aac96609ac184c
---AES_KEY---  16进制  长度:32
---AES_KEY---   2进制 长度:128
Ux38V/CaQjMWSfyFP1Qmqnkk8oqwigUZuLR5Op2FBAI=
中国大连-2023年3月14日
6
4
4
6
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. 限制;约束 )

Multiple markers at this line
	- Access restriction: The constructor 'BASE64Encoder()' is not API (restriction on required library 'C:\java\8\8\jre\lib\rt.jar')
	- Access restriction: The method 'CharacterEncoder.encode(byte[])' is not API (restriction on required library 'C:\java\8\8\jre\lib\rt.jar')
	- 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博客

---

package com.sxz.study.messageDigest;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
 
public class MessageDigestTest {
 
	public static void main(String[] args) {
 
		String md5str1 = getMessageDigestByStr("5123", "MD5");
		System.out.println(md5str1);
 
		String md5str2 = getMessageDigestByStr("5123", "SHA-256");
		System.out.println(md5str2);
 
		String md5str3 = getMessageDigestByFile("C:\\test\\to\\sss.txt");
		System.out.println(md5str3);
		
		String md5str1_method2 = getMessageDigestByStr_method2("5123", "MD5");
		System.out.println(md5str1_method2);
 
		System.out.println(String.format("%32s", "5123")); // 不足32位,前面补空格
		
		String md5str1_bug_method = getMessageDigestByStrBugMethod("5123", "MD5");
		System.out.println(md5str1_bug_method);
 
	}
 
	public static String getMessageDigestByStr(String msgStr, String algorithmStr) {
		 
		BigInteger bi = null;
 
		try {
			MessageDigest md = MessageDigest.getInstance(algorithmStr);
			byte[] buffer = md.digest(msgStr.getBytes("utf-8"));
			bi = new BigInteger(1, buffer);
 
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
 
		// 使用下面代码解决bug (PowerShell的值,有时会不相同) (MD5的值,是一个32位长度的字符串)
		String md5Str = bi.toString(16);
		      
		// MD5の場合、 不足32位,前面补空格
	             	// SHA-256の場合、 不足64位,前面补空格
		String md5StrFormat = String.format("%32s", md5Str); 
		String result = md5StrFormat.replace(" ", "0"); // 把空格替换成0
 
		return result.toUpperCase();
 
	}
 
	public static String getMessageDigestByFile(String filePath) {
 
		BigInteger bi = null;
		try {
			byte[] buffer = new byte[8192];
			int len = 0;
			MessageDigest md = MessageDigest.getInstance("MD5");
			File f = new File(filePath);
			FileInputStream fis = new FileInputStream(f);
			while ((len = fis.read(buffer)) != -1) {
				md.update(buffer, 0, len);
			}
			fis.close();
			byte[] b = md.digest();
			bi = new BigInteger(1, b);
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
 
		// 下面代码有BUG,当MD5的Hash值,第一位是0是,第一位会被省略。
		// return bi.toString(16);
 
		// 使用下面代码解决bug (MD5的值,是一个32位长度的字符串)
		String md5Str = bi.toString(16);
		String md5StrFormat = String.format("%32s", md5Str); // 不足32位,前面补空格
		String result = md5StrFormat.replace(" ", "0"); // 把空格替换成0
 
		return result.toUpperCase();
 
	}
 
	
	public static String getMessageDigestByStr_method2(String msgStr, String algorithmStr) {
 
		BigInteger bi = null;
		// 方法2
		byte[] buffer = null;
 
		try {
			MessageDigest md = MessageDigest.getInstance(algorithmStr);
			
			// 方法2
			buffer = md.digest(msgStr.getBytes("utf-8"));
			
			// 方法1
//			byte[] buffer = md.digest(msgStr.getBytes("utf-8"));
//			bi = new BigInteger(1, buffer);
 
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
 
		
		// 方法1
//		// 使用下面代码解决bug (PowerShell的值,有时会不相同) (MD5的值,是一个32位长度的字符串)
//		String md5Str = bi.toString(16);
//		      
//		// MD5の場合、 不足32位,前面补空格
//	             	// SHA-256の場合、 不足64位,前面补空格
//		String md5StrFormat = String.format("%32s", md5Str); 
//		String result = md5StrFormat.replace(" ", "0"); // 把空格替换成0
//
//		return result.toUpperCase();
		
		// 方法2
		return hex(buffer);
		
 
	}
	
    public static String hex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte aByte : bytes) {
            result.append(String.format("%02x", aByte));
            // upper case
            // result.append(String.format("%02X", aByte));
        }
        return result.toString();
    }
    
	public static String getMessageDigestByStrBugMethod(String msgStr, String algorithmStr) {
		 
		BigInteger bi = null;
 
		try {
			MessageDigest md = MessageDigest.getInstance(algorithmStr);
			byte[] buffer = md.digest(msgStr.getBytes("utf-8"));
			bi = new BigInteger(1, buffer);
 
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
 
		// 使用下面代码解决bug (PowerShell的值,有时会不相同) (MD5的值,是一个32位长度的字符串)
		String md5Str = bi.toString(16);
		      
//		// MD5の場合、 不足32位,前面补空格
//	             	// SHA-256の場合、 不足64位,前面补空格
//		String md5StrFormat = String.format("%32s", md5Str); 
//		String result = md5StrFormat.replace(" ", "0"); // 把空格替换成0
// 
//		return result.toUpperCase();
// 
		return md5Str;
	}
	
}

===

結果

037A595E6F4F0576A9EFE43154D71C18
4F9EB48D371E25B05D5DF80EEBB343C6BFB067D274301DB24DD26D26E8AEB6AB
037A595E6F4F0576A9EFE43154D71C18
037a595e6f4f0576a9efe43154d71c18
                            5123
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算法已经很旧且不够安全,不建议在实际应用中使用。

==

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class DESExample {
    public static void main(String[] args) throws Exception {
        String plainText = "This is the message to be encrypted";
        String key = "ThisIsKey";

        byte[] encryptedText = encrypt(plainText, key);
        System.out.println("Encrypted Text: " + Base64.getEncoder().encodeToString(encryptedText));

        String decryptedText = decrypt(encryptedText, key);
        System.out.println("Decrypted Text: " + decryptedText);
    }

    public static byte[] encrypt(String plainText, String key) throws Exception {
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.ENCRYPT_MODE, secretKey);

        return cipher.doFinal(plainText.getBytes(StandardCharsets.UTF_8));
    }

    public static String decrypt(byte[] encryptedText, String key) throws Exception {
        DESKeySpec desKeySpec = new DESKeySpec(key.getBytes(StandardCharsets.UTF_8));
        SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
        SecretKey secretKey = keyFactory.generateSecret(desKeySpec);

        Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);

        byte[] decryptedBytes = cipher.doFinal(encryptedText);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }
}

===

■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,不存在以上这个问题

====

DES、AES加密、MD5、SHA256等散列生成(java代码)_第1张图片

====

■加密解密的简易代码

===

package com.sxz.study.aes;

import java.util.Base64;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;

public class AESUTil {
 
	public static void main(String[] args) {
		
		
		String content = "大连";
		
		String seretKeyStr = "aabbCCdrewrwyda1235rwetrwadfafdsfABCewrwerO="; // 44
		String ivStr = "abcdefgh123456AB"; // 16
		
		String encodeStr = encodeByAES(content,seretKeyStr,ivStr);
		
		System.out.println(encodeStr);
		
		String decodeStr = decodeByAES(encodeStr,seretKeyStr,ivStr);
		
		System.out.println(decodeStr);
				
	}
 
	public static String encodeByAES(String content, String seretKeyStr, String ivStr) {
		
		String contentEncode = "";
		byte by[] = Base64.getDecoder().decode(seretKeyStr); // length:44*(6/8)= 33; 32 *8=256bit
		SecretKey secretKey = new SecretKeySpec(by, "AES");
 
		try {
			Cipher cipher = Cipher.getInstance("AES/CBC/pkcs5padding");  
			IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
			cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv);
			byte[] encryptData = cipher.doFinal(content.getBytes("UTF-8"));
			contentEncode = Base64.getEncoder().encodeToString(encryptData);
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return contentEncode;
	}
 
	
	
	public static String decodeByAES(String content, String seretKeyStr, String ivStr) {
		
		String contentDecode = "";
		byte by[] = Base64.getDecoder().decode(seretKeyStr);
		SecretKey secretKey = new SecretKeySpec(by, "AES");
 
		try {
			Cipher cipher = Cipher.getInstance("AES/CBC/pkcs5padding");  
			IvParameterSpec iv = new IvParameterSpec(ivStr.getBytes());
			cipher.init(Cipher.DECRYPT_MODE, secretKey, iv);
			byte[] decodeBase64 = Base64.getDecoder().decode(content);
			byte[] decode  = cipher.doFinal(decodeBase64);
			contentDecode = new String (decode, "UTF-8");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return contentDecode;
	}

}

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

irGJLXmvOa6NJWTlMBWxzQ==
大连

DES、AES加密、MD5、SHA256等散列生成(java代码)_第2张图片

・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字节的整数倍,那么就没有等号了。

DES、AES加密、MD5、SHA256等散列生成(java代码)_第3张图片

======

你可能感兴趣的:(java,算法,#,编码,java,开发语言)