加密算法---对称加密(AES、DES)的使用及原理
一 对称加密介绍二 对称加密案例加密工具类Aes测试des测试
一 对称加密介绍
对称加密算法中,数据发送方将明文和密钥一起经过特殊加密算法处理成密文后,将它发送出去。接收方收到密文后,若想解读原文,则需要使用加密用到的相同密钥及相同算法的逆算法对密文进行解密,才能使其恢复成原文。 它的最大优势是加/解密速度快,适用于大数据量进行加密,缺点是密钥管理困难,最典型的问题就是如何同步这个密钥,同步过程如果在公网上,不进行加密是可以抓包拿到的,那么这里就遇到了要对密钥加密的问题。 常见的对称加密算法有 AES、DES、Blowfish 等等。 对称加密的核心是只有一把密钥。
二 对称加密案例
加密工具类
package com.example.ssoreport.utils;
import lombok.extern.slf4j.Slf4j;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class EncryptUtils {
/**
* sha 加密
*
* @param str 加密信息
* @return 密文
*/
public static String sha(String str) {
String sha256Str = "";
try {
MessageDigest sha256Deget = MessageDigest.getInstance("SHA-256");
byte[] sha256Encode = sha256Deget.digest(str.getBytes());
sha256Str = ByteToHexStr(sha256Encode);
} catch (Exception e) {
log.info("FRLOG:SHA256加密异常::", e.getMessage());
}
return sha256Str;
}
/**
* byte数组转16进制字符串
*
* @param bytes 字节数组
* @return byte数组转16进制字符串
*/
private static String ByteToHexStr(byte[] bytes) {
String hexStr = "";
for (int i = 0; i
hexStr += "0" + tempHex;
} else {
hexStr += tempHex;
}
}
return hexStr;
}
/**--------------------------对称加密aes----------------------------------*/
/**
* aes 加密
*
* @param str 要加密字符串
* @param privateKey 私钥
* @return 密文
*/
public static String aesEncrypt(String str, String privateKey) {
try {
// 生成密钥对象
SecretKey secKey = generateAesKey(privateKey.getBytes());
// 获取 AES 密码器
Cipher cipher = Cipher.getInstance("AES");
// 初始化密码器(加密模型)
cipher.init(Cipher.ENCRYPT_MODE, secKey);
// 加密数据, 返回密文
byte[] cipherBytes = cipher.doFinal(str.getBytes());
// return new BASE64Encoder().encodeBuffer(cipherBytes);
return Base64.getEncoder().encodeToString(cipherBytes);
} catch (Throwable e) {
log.info("aes 加密异常", e.getMessage());
}
return null;
}
/**
* aes 解密
*
* @param str 要解码的字符串
* @param privateKey 私钥
* @return 解码信息
*/
public static String aesDecrypt(String str, String privateKey) {
try {
// 生成密钥对象
SecretKey secKey = generateAesKey(privateKey.getBytes());
// 获取 AES 密码器
Cipher cipher = Cipher.getInstance("AES");
// 初始化密码器(加密模型)
cipher.init(Cipher.DECRYPT_MODE, secKey);
byte[] decode = Base64.getDecoder().decode(str);
// 加密数据, 返回密文
byte[] cipherBytes = cipher.doFinal(decode);
return new String(cipherBytes);
} catch (Throwable e) {
log.info("aes 解密异常 ", e.getMessage());
}
return null;
}
/**
* 生成密钥对象
*/
private static SecretKey generateAesKey(byte[] key) throws Exception {
// 创建安全随机数生成器
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
// 设置 密钥key的字节数组 作为安全随机数生成器的种子
random.setSeed(key);
// 创建 AES算法生成器
KeyGenerator gen = KeyGenerator.getInstance("AES");
// 初始化算法生成器
gen.init(128, random);
// 生成 AES密钥对象, 也可以直接创建密钥对象: return new SecretKeySpec(key, ALGORITHM);
return gen.generateKey();
}
/**-------------------------- base64加密 ----------------------------------*/
/**
* base64加密
*
* @param key 要编码的字节数组
* @return 包含生成的 Base64 编码字符的字符串
*/
public static String base64Encode(byte[] key) {
String result = Base64.getEncoder().encodeToString(key);
return result;
}
/**
* base64解密
*
* @param key 被加密信息
* @return 加密信息
*/
public static byte[] base64DecodeB(String key) {
byte[] result = null;
result = Base64.getDecoder().decode(key);
return result;
}
/**
* 是否被base64加密过
*
* @param str 被加密信息
* @return true/false
*/
public static boolean isBase64(String str) {
if (str == null || str.trim().length() == 0) {
return false;
} else {
if (str.length() % 4 != 0) {
return false;
}
char[] strChars = str.toCharArray();
for (char c : strChars) {
if ((c >= 'a' && c = 'A' && c = '0' && c
return false;
}
}
return true;
}
}
/**-------------------------- 对称加密des ----------------------------------*/
/**
* des加密
*
* @param datasource 被加密信息
* @param password 秘钥
* @return 加密后的信息
*/
public static String desEncrypt(String datasource, String password) {
try {
SecureRandom random = new SecureRandom();
DESKeySpec desKey = new DESKeySpec(password.getBytes());
// 创建一个密匙工厂,然后用它把DESKeySpec转换成
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成加密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
// 现在,获取数据并加密
// 正式执行加密操作
return base64Encode(cipher.doFinal(datasource.getBytes()));
} catch (Throwable e) {
log.info("des 加密异常", e.getMessage());
}
return null;
}
/**
* des 解密
*
* @param src 加密信息
* @param password 秘钥
* @return 解密后信息
* @throws Exception
*/
public static String desDecrypt(String src, String password) {
try {
// DES算法要求有一个可信任的随机数源
SecureRandom random = new SecureRandom();
// 创建一个DESKeySpec对象
DESKeySpec desKey = new DESKeySpec(password.getBytes("UTF-8"));
// 创建一个密匙工厂
SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
// 将DESKeySpec对象转换成SecretKey对象
SecretKey securekey = keyFactory.generateSecret(desKey);
// Cipher对象实际完成解密操作
Cipher cipher = Cipher.getInstance("DES");
// 用密匙初始化Cipher对象
cipher.init(Cipher.DECRYPT_MODE, securekey, random);
// 真正开始解密操作
return new String(cipher.doFinal(base64DecodeB(src)));
} catch (Throwable e) {
log.info("des 解密异常", e.getMessage());
}
return null;
}
/**-------------------------- 非对称加密RSA ----------------------------------*/
/**
* 随机生成RSA密钥对
*
* @return privateKey, publicKey
* @throws NoSuchAlgorithmException
*/
public static Map genRSAKeyPair() throws NoSuchAlgorithmException {
// KeyPairGenerator类用于生成公钥和私钥对,基于RSA算法生成对象
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
// 初始化密钥对生成器,密钥大小为96-1024位
keyPairGen.initialize(1024, new SecureRandom());
// 生成一个密钥对,保存在keyPair中
KeyPair keyPair = keyPairGen.generateKeyPair();
// 得到私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
// 得到公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
String publicKeyString = base64Encode(publicKey.getEncoded());
// 得到私钥字符串
String privateKeyString = base64Encode(privateKey.getEncoded());
// 将公钥和私钥保存到Map
Map result = new HashMap(2);
result.put("publicKey", publicKeyString.replaceAll("\n", "").replace("\r", "").trim());
result.put("privateKey", privateKeyString.replaceAll("\n", "").replace("\r", "").trim());
return result;
}
/**
* rsa 加密
*
* @param str 被加密信息
* @param publicKey 公钥
* @return 加密后的信息
* @throws Exception
*/
public static String rsaEncrypt(String str, String publicKey) throws Exception {
//base64编码的公钥
byte[] decoded = base64DecodeB(publicKey);
RSAPublicKey pubKey = (RSAPublicKey) KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(decoded));
//RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
String outStr = base64Encode(cipher.doFinal(str.getBytes("UTF-8")));
return outStr;
}
/**
* rsa解密
*
* @param str 加密信息
* @param privateKey 私钥
* @return 解密后信息
* @throws Exception
*/
public static String rsaDecrypt(String str, String privateKey) throws Exception {
//64位解码加密后的字符串
byte[] inputByte = base64DecodeB(str);
//base64编码的私钥
byte[] decoded = base64DecodeB(privateKey);
RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, priKey);
String outStr = new String(cipher.doFinal(inputByte));
return outStr;
}
}
Aes测试
@Test
void AesTest() {
String key = "ueriqouoit";
String s = EncryptUtils.aesEncrypt("我是西瓜", key);
System.out.println("s = " + s);
String s1 = EncryptUtils.aesDecrypt(s, key);
System.out.println("s1 = " + s1);
// s = fMyX4cmgZ01M86YkfX/t7g==
// s1 = 我是西瓜
/**错误秘钥解密*/
EncryptUtils.aesDecrypt(s, "hasdgiuhui");
// c.example.ssoreport.utils.EncryptUtils : aes 解密异常
//s1 = null
}
des测试
@Test
void DesTest() {
String key = "ueriqouoit";
String s = EncryptUtils.desEncrypt("我是西瓜", key);
System.out.println("s = " + s);
String s1 = EncryptUtils.desDecrypt(s, key);
System.out.println("s1 = " + s1);
// s = q0jiEs2Sl2BduQOFeHtKKA==
// s1 = 我是西瓜
/**错误秘钥解密*/
String s2 = EncryptUtils.desDecrypt(s, "hasdgiuhui");
System.out.println("s2 = " + s2);
// s2 = �(4P�x���%mڠ�
}
|