赞
踩
加密分为三种:
意思:对称加密是一种加密方法,它使用相同的密钥进行数据的加密和解密。这意味着发送方和接收方必须共享同一个密钥,并且在通信之前确保这个密钥的安全传输。
解释:因为加解密使用的是同一把“钥匙”,所以这种加密方式相对简单高效,适合处理大量数据的加密。然而,密钥的安全分发是一个挑战,一旦密钥泄露,加密信息就可能被破解。
用途:对称加密广泛应用于数据存储、文件加密、网络通信等领域,比如AES(高级加密标准)常用于无线网络通信加密、银行交易数据保护等。
意思:非对称加密采用了两个密钥,分别是公钥和私钥。公钥可以公开,用于加密信息;私钥必须保密,用于解密信息。知道公钥并不能推算出私钥,这保证了信息的安全性。
解释:非对称加密的优势在于解决了密钥分发的问题,因为公钥可以公开传播,而私钥由接收方安全保管。这种方式虽然安全,但由于加密和解密过程更为复杂,处理速度较慢,通常不直接用于大量数据的加密,而是用于加密小量数据如密钥交换、数字签名等场景。
用途:非对称加密常用于SSL/TLS协议中的网站安全连接、SSH远程登录、电子邮件加密(如PGP)、数字签名和身份认证等。
意思:摘要加密实际上并不属于传统意义上的加密,因为它不可逆,即从摘要不能还原出原始信息。它将任意长度的输入(消息)转换为固定长度的输出(摘要或哈希值),目的是验证数据的完整性和唯一性。
解释:哈希函数具有抗碰撞性,即不同输入很难得到相同的输出。即便输入信息只改变一点点,输出的哈希值也会完全不同。这种特性使得摘要加密非常适合用于数据校验、密码存储和数字签名等场景。
用途:
每种加密方式都有其独特的应用场景和优势,实际中往往结合使用,以达到既高效又安全的目的。
糊涂工具对上诉加密提供了实现:
https://doc.hutool.cn/pages/crypto/index/
SM3 加密
SM3是一种由中国国家密码管理局制定的密码散列函数
标准,类似于SHA-256,用于生成一个固定长度的摘要。SM3的设计目标是提供与国际标准相当的安全强度,同时满足中国国内的信息安全需求。SM3的输出长度为256位,它基于Merkle-Damgård结构,采用了一种称为Piling-up Lemma的扩散技术,以增强算法的安全性。
SM4 加密
SM4是中国国家密码管理局发布的分组密码算法,它是一种对称加密算法
,类似于AES(Advanced Encryption Standard)。SM4设计用于多种应用场景,包括但不限于数据加密、消息认证码(MAC)生成和随机数生成。SM4的工作模式包括ECB(电子密码本)、CBC(密码块链接)、CFB(密码反馈)和OFB(输出反馈)。
AES(Advanced Encryption Standard,高级加密标准)
AES是目前广泛使用的一种对称加密算法,由比利时密码学家Joan Daemen和Vincent Rijmen设计,最初被称为Rijndael。2001年,美国国家标准与技术研究院(NIST)正式采纳AES作为联邦信息处理标准(FIPS PUB 197),用于替换旧的DES加密标准。
特点:
DES(Data Encryption Standard,数据加密标准)
DES是一种早期的对称加密算法,由IBM开发,并在1977年被美国国家标准局(现NIST)采纳为官方标准。DES曾是全球最广泛使用的加密算法之一,但在21世纪初,由于其密钥长度仅为56位,开始显露出安全性不足的问题。
特点:
AES和DES都是对称加密算法,但
AES在安全性、性能和密钥长度方面都优于DES
,因此AES已经成为现代加密应用的首选标准。DES在历史上占有重要地位,但如今在安全性要求较高的场合已被AES所取代。
package cn.creatoo.why.util; import org.bouncycastle.crypto.digests.SM3Digest; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import java.io.UnsupportedEncodingException; import java.security.Security; import java.util.Arrays; /** * SM3 工具类 */ public class Sm3Utils { /** * 编码格式 */ private static final String ENCODING = "UTF-8"; static { Security.addProvider(new BouncyCastleProvider()); } /** * @param paramStr 要sm3加密的内容 * @return sm3加密后密文 */ public static String encrypt(String paramStr) { String resultHexString = ""; try { byte[] srcData = paramStr.getBytes(ENCODING); byte[] hash = hash(srcData); resultHexString = ByteUtils.toHexString(hash); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return resultHexString; } public static byte[] hash(byte[] srcData) { SM3Digest sm3Digest = new SM3Digest(); sm3Digest.update(srcData, 0, srcData.length); byte[] bytes = new byte[sm3Digest.getDigestSize()]; sm3Digest.doFinal(bytes, 0); return bytes; } /** * @param str 明文 * @param hexString 密文 * @return 明文密文对比结果 */ public static boolean verify(String str, String hexString) { boolean flag = false; try { byte[] srcData = str.getBytes(ENCODING); byte[] sm3Hash = ByteUtils.fromHexString(hexString); byte[] hash = hash(srcData); if (Arrays.equals(hash, sm3Hash)) { flag = true; } } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return flag; } }
package cn.creatoo.why.util; import org.bouncycastle.jce.provider.BouncyCastleProvider; import java.security.Key; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SecureRandom; import java.security.Security; import java.util.Arrays; import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.spec.SecretKeySpec; import org.bouncycastle.pqc.math.linearalgebra.ByteUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.security.Security; /** * sm4加密算法工具类 * * @explain sm4加密、解密与加密结果验证 * 可逆算法 */ @Component public class SM4Util { // 一串字符串如:KA34D430ERER45K899X9987M90A6L76A @Value("${dataSync.sm4Secret}") private String key; static { Security.addProvider(new BouncyCastleProvider()); } private static final String ENCODING = "UTF-8"; public static final String ALGORITHM_NAME = "SM4"; // 加密算法/分组加密模式/分组填充方式 // PKCS5Padding-以8个字节为一组进行分组加密 // 定义分组加密模式使用:PKCS5Padding public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS5Padding"; // 128-32位16进制;256-64位16进制 public static final int DEFAULT_KEY_SIZE = 128; /** * 生成ECB暗号 * * @param algorithmName 算法名称 * @param mode 模式 * @param key * @return * @throws Exception * @explain ECB模式(电子密码本模式:Electronic codebook) */ private static Cipher generateEcbCipher(String algorithmName, int mode, byte[] key) throws Exception { Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME); Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME); cipher.init(mode, sm4Key); return cipher; } /** * 自动生成密钥 * * @return * @throws NoSuchAlgorithmException * @throws NoSuchProviderException * @explain */ public static byte[] generateKey() throws Exception { return generateKey(DEFAULT_KEY_SIZE); } /** * @param keySize * @return * @throws Exception * @explain */ public static byte[] generateKey(int keySize) throws Exception { KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME); kg.init(keySize, new SecureRandom()); return kg.generateKey().getEncoded(); } /** * sm4加密 * * @param paramStr 待加密字符串 * @return 返回16进制的加密字符串 * @throws Exception * @explain 加密模式:ECB * 密文长度不固定,会随着被加密字符串长度的变化而变化 * 16进制密钥(忽略大小写) */ public String encrypt(String paramStr) throws Exception { String cipherText = ""; // 16进制字符串-->byte[] byte[] keyData = ByteUtils.fromHexString(key); // String-->byte[] byte[] srcData = paramStr.getBytes(ENCODING); // 加密后的数组 byte[] cipherArray = encrypt_Ecb_Padding(keyData, srcData); // byte[]-->hexString cipherText = ByteUtils.toHexString(cipherArray); return cipherText; } /** * 加密模式之Ecb * * @param key * @param data * @return * @throws Exception * @explain */ public static byte[] encrypt_Ecb_Padding(byte[] key, byte[] data) throws Exception { Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key); return cipher.doFinal(data); } /** * sm4解密 * * @param cipherText 16进制的加密字符串(忽略大小写) * @return 解密后的字符串 * @throws Exception * @explain 解密模式:采用ECB * 16进制密钥 */ public String decryptEcb(String cipherText) throws Exception { // 用于接收解密后的字符串 String decryptStr = ""; // hexString-->byte[] byte[] keyData = ByteUtils.fromHexString(key); // hexString-->byte[] byte[] cipherData = ByteUtils.fromHexString(cipherText); // 解密 byte[] srcData = decrypt_Ecb_Padding(keyData, cipherData); // byte[]-->String decryptStr = new String(srcData, ENCODING); return decryptStr; } /** * 解密 * * @param key * @param cipherText * @return * @throws Exception * @explain */ public static byte[] decrypt_Ecb_Padding(byte[] key, byte[] cipherText) throws Exception { Cipher cipher = generateEcbCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key); return cipher.doFinal(cipherText); } /** * 校验加密前后的字符串是否为同一数据 * * @param cipherText 16进制加密后的字符串 * @param paramStr 加密前的字符串 * @return 是否为同一数据 * @throws Exception * @explain 16进制密钥(忽略大小写) */ public boolean verifyEcb(String cipherText, String paramStr) throws Exception { // 用于接收校验结果 boolean flag = false; // hexString-->byte[] byte[] keyData = ByteUtils.fromHexString(key); // 将16进制字符串转换成数组 byte[] cipherData = ByteUtils.fromHexString(cipherText); // 解密 byte[] decryptData = decrypt_Ecb_Padding(keyData, cipherData); // 将原字符串转换成byte[] byte[] srcData = paramStr.getBytes(ENCODING); // 判断2个数组是否一致 flag = Arrays.equals(decryptData, srcData); return flag; } }
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64; import org.bouncycastle.jce.provider.BouncyCastleProvider; import javax.crypto.Cipher; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; import java.security.Security; public class ADCryptUtils { static { try { Security.addProvider(new BouncyCastleProvider()); } catch (Exception e) { e.printStackTrace(); } } // vi 076ce634d7da11eb private static final byte[] DES_DEFAULT_KEY=new byte[] { 10, 20, 50, 99, 101, 54, 51, 52, 100, 55, 100, 97, 49, 49, 112, 98 }; private static final byte[] AES_DEFAULT_KEY=new byte[] { 10, 20, 50, 99, 101, 54, 51, 52, 100, 55, 100, 97, 49, 49, 112, 98 }; /** * content: 加密内容 */ public static String encryptAes(String content) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey secretKey = new SecretKeySpec(AES_DEFAULT_KEY, "AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey,new IvParameterSpec(AES_DEFAULT_KEY)); byte[] encrypted = cipher.doFinal(content.getBytes()); return Base64.encode(encrypted); } /** * content: 解密内容 */ public static String decryptAes(String base64Content) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey secretKey = new SecretKeySpec(AES_DEFAULT_KEY, "AES"); cipher.init(Cipher.DECRYPT_MODE, secretKey,new IvParameterSpec(AES_DEFAULT_KEY)); byte[] content = Base64.decode(base64Content); byte[] encrypted = cipher.doFinal(content); return new String(encrypted); } /** * content: 加密内容 */ public static String encryptDes(String content) throws Exception { Cipher cipher = Cipher.getInstance("DES"); SecretKey secretKey = new SecretKeySpec(DES_DEFAULT_KEY, "DES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] encrypted = cipher.doFinal(content.getBytes()); return Base64.encode(encrypted); } /** * content: 解密内容 */ public static String decryptDes(String base64Content) throws Exception { Cipher cipher = Cipher.getInstance("DES"); SecretKey secretKey = new SecretKeySpec(DES_DEFAULT_KEY, "DES"); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] content = Base64.decode(base64Content); byte[] encrypted = cipher.doFinal(content); return new String(encrypted); } /** * content: 加密内容 * slatKey: 加密的盐,16位字符串 */ public static String encryptAes(String content, String slatKey) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey,new IvParameterSpec(AES_DEFAULT_KEY)); byte[] encrypted = cipher.doFinal(content.getBytes()); return Base64.encode(encrypted); } /** * content: 解密内容 * slatKey: 加密时使用的盐,16位字符串 */ public static String decryptAes(String base64Content, String slatKey) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES"); cipher.init(Cipher.DECRYPT_MODE, secretKey,new IvParameterSpec(AES_DEFAULT_KEY)); byte[] content = Base64.decode(base64Content); byte[] encrypted = cipher.doFinal(content); return new String(encrypted); } /** * content: 加密内容 * slatKey: 加密的盐,16位字符串 * vectorKey: 加密的向量,16位字符串 */ public static String encryptAes(String content, String slatKey, String vectorKey) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES"); IvParameterSpec iv = new IvParameterSpec(vectorKey.getBytes()); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); byte[] encrypted = cipher.doFinal(content.getBytes()); return Base64.encode(encrypted); } /** * content: 解密内容(base64编码格式) * slatKey: 加密时使用的盐,16位字符串 * vectorKey: 加密时使用的向量,16位字符串 */ public static String decryptAes(String base64Content, String slatKey, String vectorKey) throws Exception { Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "AES"); IvParameterSpec iv = new IvParameterSpec(vectorKey.getBytes()); cipher.init(Cipher.DECRYPT_MODE, secretKey, iv); byte[] content = Base64.decode(base64Content); byte[] encrypted = cipher.doFinal(content); return new String(encrypted); } /** * content: 加密内容 * slatKey: 加密的盐,8位字符串 */ public static String encryptDes(String content, String slatKey) throws Exception { Cipher cipher = Cipher.getInstance("DES"); SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "DES"); cipher.init(Cipher.ENCRYPT_MODE, secretKey); byte[] encrypted = cipher.doFinal(content.getBytes()); return Base64.encode(encrypted); } /** * content: 解密内容 * slatKey: 加密时使用的盐,8位字符串 */ public static String decryptDes(String base64Content, String slatKey) throws Exception { Cipher cipher = Cipher.getInstance("DES"); SecretKey secretKey = new SecretKeySpec(slatKey.getBytes(), "DES"); cipher.init(Cipher.DECRYPT_MODE, secretKey); byte[] content = Base64.decode(base64Content); byte[] encrypted = cipher.doFinal(content); return new String(encrypted); } public static void main(String[] args) { try { String encryptDes = ADCryptUtils.encryptAes("测试AES加密"); System.out.println(encryptDes); String decryptDes = ADCryptUtils.decryptAes(encryptDes); System.out.println(decryptDes); } catch (Exception e) { e.printStackTrace(); } } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。