在当今的信息时代,数据的安全性显得尤为重要,加密算法作为保障数据安全的核心手段,在过去的几十年中经历了巨大的发展。信息加密是前后端开发都经常需要使用到的技术,应用场景包括了数据存储、网络通信、身份认证等等,不同的应用场景也会需要使用到不同的签名加密算法,或者需要搭配不一样的签名加密算法来达到业务目标。这里简单的给大家介绍几种常见的签名加密算法和一些典型场景下的应用。
MD5
是一种广泛使用的散列算法,产生一个128
位哈希值。它通常用于验证数据的完整性和一致性,但由于存在碰撞攻击,现在被认为不够安全(攻击者可以通过暴力破解或彩虹表攻击等方式破解),虽然可以通过加盐,也就是对在原文里再加上一些不固定的字符串来缓解,但是完全可以用更安全的SHA
系列算法替代
public class MD5 {
private static final String MD5_ALGORITHM = "MD5";
public static String encrypt(String data) throws Exception {
// 获取MD5算法实例
MessageDigest messageDigest = MessageDigest.getInstance(MD5_ALGORITHM);
// 计算散列值
byte[] digest = messageDigest.digest(data.getBytes());
Formatter formatter = new Formatter();
// 补齐前导0,并格式化
for (byte b : digest) {
formatter.format("%02x", b);
}
return formatter.toString();
}
public static void main(String[] args) throws Exception {
String data = "Hello World";
String encryptedData = encrypt(data);
System.out.println("加密后的数据:" + encryptedData);
}
}
SHA(Secure Hash Algorithm)
系列算法是一组密码散列函数,用于将任意长度的数据映射为固定长度的散列值。SHA系列算法由美国国家安全局(NSA)
于1993
年设计,目前共有SHA-1
(存在缺陷,不推荐使用)、SHA-2
、SHA-3
三种版本SHA-2
算法包括SHA-224
、SHA-256
、SHA-384
和SHA-512
四种散列函数,分别将任意长度的数据映射为224位
、256位
、384位
和512位
的散列值public class SHA256 {
private static final String SHA_256_ALGORITHM = "SHA-256";
public static String encrypt(String data) throws Exception {
//获取SHA-256算法实例
MessageDigest messageDigest = MessageDigest.getInstance(SHA_256_ALGORITHM);
//计算散列值
byte[] digest = messageDigest.digest(data.getBytes());
StringBuilder stringBuilder = new StringBuilder();
//将byte数组转换为15进制字符串
for (byte b : digest) {
stringBuilder.append(Integer.toHexString((b & 0xFF) | 0x100), 1, 3);
}
return stringBuilder.toString();
}
public static void main(String[] args) throws Exception {
String data = "Hello World";
String encryptedData = encrypt(data);
System.out.println("加密后的数据:" + encryptedData);
}
}
SHA-2
算法之所以比MD5
强,主要有两个原因:
SHA-256
算法的散列值长度为256位
,而MD5
算法的散列值长度为128位
,这就提高了攻击者暴力破解或者彩虹表攻击的难度SHA
算法采用了更复杂的运算过程和更多的轮次,使得攻击者更难以通过预计算或巧合找到碰撞,但是实际应用中加盐还是必不可少的DES
、3DES
、AES
等。其中,AES
算法是目前使用最广泛的对称加密算法之一,具有比较高的安全性和加密效率
AES
(高级加密标准):AES
是一种常用的对称加密算法,被广泛用于政府和商业领域的数据加密。它采用固定长度的明文块和密钥进行加密,提供128位
、192位
和256位
三种加密强度DES
(数据加密标准):DES
是一种较旧的对称加密算法,使用56位
密钥和8字节
的块大小。由于其密钥长度较短,现在已被认为不够安全,已被AES
取代3DES
(三重数据加密算法):3DES
是对DES
的一种扩展,通过使用三个DES
密钥进行三次加密来提供更高的安全性DES
算法使用56位
密钥对数据进行加密,加密过程中使用了置换、替换、异或等运算,具有较高的安全性,但是这也是过去式了,由于密匙过短,还是比较容易被暴力破解的
public class DES {
private static final String DES_ALGORITHM = "DES";
/**
* DES加密
*
* @param data 待加密的数据
* @param key 密钥,长度必须为8位
* @return 加密后的数据,使用Base64编码
*/
public static String encrypt(String data, String key) throws Exception {
// 根据密钥生成密钥规范
KeySpec keySpec = new DESKeySpec(key.getBytes());
// 根据密钥规范生成密钥工厂
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
// 根据密钥工厂和密钥规范生成密钥
SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
// 根据加密算法获取加密器
Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
// 初始化加密器,设置加密模式和密钥
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
// 加密数据
byte[] encryptedData = cipher.doFinal(data.getBytes());
// 对加密后的数据进行Base64编码
return Base64.getEncoder().encodeToString(encryptedData);
}
/**
* DES解密
*
* @param encryptedData 加密后的数据,使用Base64编码
* @param key 密钥,长度必须为8位
* @return 解密后的数据
*/
public static String decrypt(String encryptedData, String key) throws Exception {
// 根据密钥生成密钥规范
KeySpec keySpec = new DESKeySpec(key.getBytes());
// 根据密钥规范生成密钥工厂
SecretKeyFactory secretKeyFactory = SecretKeyFactory.getInstance(DES_ALGORITHM);
// 根据密钥工厂和密钥规范生成密钥
SecretKey secretKey = secretKeyFactory.generateSecret(keySpec);
// 对加密后的数据进行Base64解码
byte[] decodedData = Base64.getDecoder().decode(encryptedData);
// 根据加密算法获取解密器
Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
// 初始化解密器,设置解密模式和密钥
cipher.init(Cipher.DECRYPT_MODE, secretKey);
// 解密数据
byte[] decryptedData = cipher.doFinal(decodedData);
// 将解密后的数据转换为字符串
return new String(decryptedData);
}
public static void main(String[] args) throws Exception {
String data = "Hello World";
String key = "12345678";
String encryptedData = encrypt(data, key);
System.out.println("加密后的数据:" + encryptedData);
String decryptedData = decrypt(encryptedData, key);
System.out.println("解密后的数据:" + decryptedData);
}
}
AES(Advanced Encryption Standard)
即高级加密标准,是一种对称加密算法,被广泛应用于数据加密和保护领域。AES
算法使用的密钥长度为128位
、192位
或256位
,比DES
算法的密钥长度更长,安全性更高
public class AES {
private static final String AES_ALGORITHM = "AES";
// AES加密模式为CBC,填充方式为PKCS5Padding
private static final String AES_TRANSFORMATION = "AES/CBC/PKCS5Padding";
// AES密钥为16位
private static final String AES_KEY = "1234567890123456";
// AES初始化向量为16位
private static final String AES_IV = "abcdefghijklmnop";
/**
* AES加密
*
* @param data 待加密的数据
* @return 加密后的数据,使用Base64编码
*/
public static String encrypt(String data) throws Exception {
// 将AES密钥转换为SecretKeySpec对象
SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(), AES_ALGORITHM);
// 将AES初始化向量转换为IvParameterSpec对象
IvParameterSpec ivParameterSpec = new IvParameterSpec(AES_IV.getBytes());
// 根据加密算法获取加密器
Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
// 初始化加密器,设置加密模式、密钥和初始化向量
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
// 加密数据
byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
// 对加密后的数据使用Base64编码
return Base64.getEncoder().encodeToString(encryptedData);
}
/**
* AES解密
*
* @param encryptedData 加密后的数据,使用Base64编码
* @return 解密后的数据
*/
public static String decrypt(String encryptedData) throws Exception {
// 将AES密钥转换为SecretKeySpec对象
SecretKeySpec secretKeySpec = new SecretKeySpec(AES_KEY.getBytes(), AES_ALGORITHM);
// 将AES初始化向量转换为IvParameterSpec对象
IvParameterSpec ivParameterSpec = new IvParameterSpec(AES_IV.getBytes());
// 根据加密算法获取解密器
Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
// 初始化解密器,设置解密模式、密钥和初始化向量
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
// 对加密后的数据使用Base64解码
byte[] decodedData = Base64.getDecoder().decode(encryptedData);
// 解密数据
byte[] decryptedData = cipher.doFinal(decodedData);
// 返回解密后的数据
return new String(decryptedData, StandardCharsets.UTF_8);
}
public static void main(String[] args) throws Exception {
String data = "Hello World";
String encryptedData = encrypt(data);
System.out.println("加密后的数据:" + encryptedData);
String decryptedData = decrypt(encryptedData);
System.out.println("解密后的数据:" + decryptedData);
}
}
非对称加密算法是指加密和解密使用不同密钥的加密算法,但是相互匹配,一个称为公钥,另一个称为私钥。使用其中的一个加密,则使用另一个进行解密,例如使用公钥加密,则需要使用私钥解密
public class RSA {
private static final String RSA_ALGORITHM = "RSA";
/**
* 生成RSA密钥对
*
* @return RSA密钥对
*/
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(RSA_ALGORITHM);
keyPairGenerator.initialize(2048); // 密钥大小为2048位
return keyPairGenerator.generateKeyPair();
}
/**
* 使用公钥加密数据
*
* @param data 待加密的数据
* @param publicKey 公钥
* @return 加密后的数据
*/
public static String encrypt(String data, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().encodeToString(encryptedData);
}
/**
* 使用私钥解密数据
*
* @param encryptedData 加密后的数据
* @param privateKey 私钥
* @return 解密后的数据
*/
public static String decrypt(String encryptedData, PrivateKey privateKey) throws Exception {
byte[] decodedData = Base64.getDecoder().decode(encryptedData);
Cipher cipher = Cipher.getInstance(RSA_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(decodedData);
return new String(decryptedData, StandardCharsets.UTF_8);
}
public static void main(String[] args) throws Exception {
KeyPair keyPair = generateKeyPair();
PublicKey publicKey = keyPair.getPublic();
PrivateKey privateKey = keyPair.getPrivate();
String data = "Hello World";
String encryptedData = encrypt(data, publicKey);
System.out.println("加密后的数据:" + encryptedData);
String decryptedData = decrypt(encryptedData, privateKey);
System.out.println("解密后的数据:" + decryptedData);
}
}
RSA
算法的优点是安全性高,公钥可以公开,私钥必须保密,保证了数据的安全性;可用于数字签名、密钥协商等多种应用场景HTTPS请求
:用户使用浏览器输入网址访问HTTPS站点
,准备发起HTTPS请求
服务器的公钥
、颁发者(证书颁发机构)
等信息非对称加密
和散列算法
证书颁发机构
的公钥
对证书进行验证,保证证书的真实性和合法性证书中的公钥
对服务端的数字签名
进行验证,保证服务器的身份和数据的完整性散列算法
计算出散列值,和证书种的散列值
进行对比,保证证书的完整性对称密钥
:客户端生成一个随机数
,作为对称密钥客户端
使用服务器的公钥
对随机数进行加密,然后将加密后的信息传输给服务器
私钥解密(客户端公钥加密、服务器私钥解密)
客户端发送的对称密钥,得到对称密钥
对称密钥
进行通信:服务器与浏览器都使用对称密钥对数据进行加密和解密,以此确保数据传输的安全性在数据传输的过程中,也用到了散列算法: