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

news/2025/3/15 21:45:08/

目录

■前言

■代码

■运行效果

■其它

・Access restriction. (访问限制)

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

■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"); // 把空格替换成0System.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)操作,第二个参数为使用的KEYcipher.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)操作,第二个参数为使用的KEYcipher.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"); // 把空格替换成0return 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"); // 把空格替换成0return result.toUpperCase();}public static String getMessageDigestByStr_method2(String msgStr, String algorithmStr) {BigInteger bi = null;// 方法2byte[] buffer = null;try {MessageDigest md = MessageDigest.getInstance(algorithmStr);// 方法2buffer = 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();// 方法2return 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
037a595e6f4f0576a9efe43154d71c185123
37a595e6f4f0576a9efe43154d71c18

===

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

====

====

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


http://www.ppmy.cn/news/246727.html

相关文章

玩会儿LVM2

首先新建几个分区&#xff0c;再调个格式。 Command (m for help): t Partition number (1-9): 8 Hex code (type L to list codes): 8e Changed system type of partition 8 to 8e (Linux LVM) Command (m for help): t Partition number (1-9): 9 Hex code (type L to list…

二十一、C++11(中)

文章目录 一、左值&右值&#xff08;一&#xff09;基本概念1.左值是什么2.右值是什么 &#xff08;二&#xff09;左值引用和右值引用1.左值引用2.右值引用 二、右值引用使用场景和意义&#xff08;一&#xff09;引入&#xff08;二&#xff09;左值引用的使用场景&#…

Activiti6.0(四)流程变量的使用

目录 一、前言 二、流程变量介绍 1、设置流程变量 2、在流程线上使用流程变量 3、流程变量存储 4、经验总结 一、前言 流程变量也是流程使用中一个很重要的东西&#xff0c;主要承担传递业务参数的作用&#xff0c;其作用范围仅在当前流程实例中有效&#xff0c;因此也常…

Kubeadm部署高可用K8S集群

目录&#xff1a; 1. 设备清单2. 初始环境准备2.1 主机名解析2.2 关闭防火墙及SElinux2.3 关闭NetworkManager2.4 进行时间同步2.5 升级系统&#xff08;可选&#xff0c;我没做&#xff09;命令如下&#xff1a;2.6 升级内核2.7 设置安装源2.7.1 设置k8s源2.7.2 设置docker源 …

020 ceph作openstack的后端存储

一、使用ceph做glance后端 1.1 创建用于存储镜像的池 [rootserverc ~]# ceph osd pool create images 128 128 pool images created [rootserverc ~]# ceph osd pool application enable images rbd enabled application rbd on pool images 1.2 创建client.glance账号并授权 …

java crontab_CrontabGenerate 本项目主要是为了生成 表达式。 Java Develop 272万源代码下载- www.pudn.com...

文件名称: CrontabGenerate下载 收藏√ [ 5 4 3 2 1 ] 开发工具: Java 文件大小: 957 KB 上传时间: 2017-03-11 下载次数: 0 详细说明:本项目主要是为了生成crontab表达式。-for crontab el generate 文件列表(点击判断是否您需要的文件,如果是垃圾请在下面评价投诉):…

Redis 集群架构的搭建基于5.03

哨兵架构存在的一些缺陷&#xff1a; 1. 瞬断问题&#xff0c;哨兵架构中&#xff0c;当主节点挂断后需要选举&#xff0c;然后切换&#xff0c;中间有几秒到几十秒的服务暂停时间 2. 高并发受限问题&#xff0c;哨兵对外只有一个节点提供写服务&#xff0c;一台就几w的QPS。…

getticket时errcode 40097 errmsg invalid args hint

{"errcode":40097,"errmsg":"invalid args hint: [*****************]"} 结尾需加上&offset_type1 https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_tokenACCESS_TOKEN&typejsapi&offset_type1 其他见文档&#xff…