数据安全这事儿,现在谁也躲不过。从在线支付到身份验证,加密算法就像是互联网的“安全套”,保护着我们不被“爆菊”。但加密这玩意儿,水深得很,一不小心就翻车。今天就来扒一扒那些常见的加密算法,告诉你哪些是“老司机”,哪些是“坑”。
为啥要加密?简单粗暴地说,就是怕被别人“偷窥”。前端后端开发,加密技术那是家常便饭:
密码明文?那是作死!加密后的密文才是王道。银行卡号、身份证号,这些敏感信息必须“穿上衣服”才能出门。支付接口这种“高危地带”,没签名验证?等着被“薅羊毛”吧!
不同场景,加密姿势也得不一样。下面就来聊聊几种常见的加密算法,看看它们都有啥“癖好”。
加密算法大乱斗:不可逆、对称、非对称,谁才是你的菜?
加密算法这玩意儿,门道多得很。简单来说,可以分成不可逆加密和可逆加密两大派。可逆加密又分对称加密和非对称加密,听着就头大?别慌,咱慢慢来。
一锤子买卖:不可逆加密,用完就扔?
不可逆加密,顾名思义,就是加密后就回不去了。你想从密文还原成原文?没门!这种算法,就像渣男,用完就扔,不留一点痕迹。
哈希算法就是典型的不可逆加密。明文经过哈希算法,生成一串固定长度的哈希值。这哈希值,跟明文长短没关系,就像人的指纹,独一无二。
MD5、SHA1、SHA-256,这些都是哈希算法家族的成员。它们经常出现在数字签名、消息认证和密码存储等场景。
哈希算法不需要密钥?没错!但也有例外,比如HMAC算法,它就需要一把“钥匙”。
MD5:廉颇老矣,尚能饭否?
MD5,Message-Digest Algorithm 5 的缩写,听着挺唬人,其实就是一种哈希算法。它能把任意长度的数据,变成一串固定长度的哈希值。MD5 输出的哈希值是 128 位的,通常用 32 个十六进制数字表示。
来,看看 MD5 算法的 Java 代码实现:
import java.security.MessageDigest;
import java.util.Formatter;
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();
// 补充前导零并格式化
for (byte b : digest) {
formatter.format("%02x", b);
}
return formatter.toString();
}
public static void main(String[] args) throws Exception {
String data = "Hello Dylan";
String encryptedData = encrypt(data);
System.out.println("Encrypted data: " + encryptedData);
}
}
跑一下,你会得到这样的结果:
Encrypted data: ac1fbf0692d337780a0fbffb2798ac96
MD5 速度快,输出长度固定,应用广泛,这些都是它的优点。
但作为一种加密算法,MD5 最大的问题就是:不!安!全!
MD5 已经被破解了!攻击者可以通过暴力破解或者彩虹表攻击,找到和原数据相同的哈希值,从而破解数据。
虽然加盐(在原文中加点“佐料”)可以提高安全性,但为啥不用更安全的 SHA 系列算法呢?
SHA-256:MD5 的升级版,更安全的选择?
SHA(Secure Hash Algorithm)是一系列加密哈希函数,能把任意长度的数据,变成固定长度的哈希值。SHA 家族有三个版本:SHA-1、SHA-2 和 SHA-3。
SHA-1 已经过时了,不建议使用。
SHA-2 包括 SHA-224、SHA-256、SHA-384、SHA-512 这四个“兄弟”,它们分别生成 224 位、256 位、384 位和 512 位的哈希值。
来看看最常用的 SHA-256 的 Java 代码实现:
import java.security.MessageDigest;
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();
// 将字节数组转换为十六进制字符串
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 Dylan";
String encryptedData = encrypt(data);
System.out.println("Encrypted data: " + encryptedData);
}
}
运行结果如下:
Encrypted data: 2ff61b5259b01a8ef4e6dae816d3f26b4b9cbc3957a6a9d0aceb49d11d5d950e
SHA-2 比 MD5 更强,主要体现在:
哈希值更长:SHA-256 是 256 位的,MD5 只有 128 位。这意味着攻击者需要更多的时间和资源才能破解。抗碰撞性更强:SHA 算法使用了更复杂的运算,攻击者更难找到碰撞(两个不同的输入,产生相同的哈希值)。
当然,SHA-2 也不是万无一失的。所有哈希算法都有被暴力破解或者彩虹表攻击的风险。所以,加盐还是很有必要的。
对称加密:一把钥匙开一把锁,简单粗暴?
对称加密算法,就是用同一把钥匙来加密和解密。
加密解密都用同一把钥匙,所以钥匙的安全性至关重要。一旦钥匙泄露,数据就等于裸奔了。
DES、3DES、AES 都是常见的对称加密算法。其中,AES 是目前最流行的,安全性高,效率也不错。
DES:老掉牙的加密算法,该淘汰了吗?
DES(Data Encryption Standard),数据加密标准,是 IBM 在 1975 年搞出来的,算是对称加密算法里的“老前辈”了。
DES 使用 56 位的密钥进行加密,用到了置换、替换、异或等操作,安全性还算可以。
看看 DES 算法的 Java 代码实现:
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.DESKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.SecureRandom;
import java.util.Base64;
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 = Cipher.getInstance(DES_ALGORITHM);
// 初始化Cipher为加密模式并设置密钥。
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 = Cipher.getInstance(DES_ALGORITHM);
// 初始化Cipher为解密模式并设置密钥。
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 Dylan";
String key = "12345678";
String encryptedData = encrypt(data, key);
System.out.println("加密后的数据: " + encryptedData);
String decryptedData = decrypt(encryptedData, key);
System.out.println("解密后的数据: " + decryptedData);
}
}
运行结果:
加密后的数据: 3D12G4wkjn4CESZ5YgCeKA==
解密后的数据: Hello Dylan
DES 速度快,但安全性不高。因为它的密钥太短了,容易被暴力破解,也容易受到差分攻击。
所以,还是用更安全的 3DES 或者 AES 吧。
AES:对称加密界的扛把子,安全又高效
AES(Advanced Encryption Standard),高级加密标准,是目前最流行的对称加密算法。AES 的密钥长度可以是 128 位、192 位或者 256 位,比 DES 更长,安全性也更高。
来看看 AES 算法的 Java 代码实现:
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;
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());
// 获取AES算法的Cipher实例。
Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
// 初始化Cipher为加密模式,设置密钥和初始化向量。
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
// 加密数据。
byte[] encryptedData = cipher.doFinal(data.getBytes(java.nio.charset.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());
// 获取AES算法的Cipher实例。
Cipher cipher = Cipher.getInstance(AES_TRANSFORMATION);
// 初始化Cipher为解密模式,设置密钥和初始化向量。
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, ivParameterSpec);
// 使用Base64解码加密数据。
byte[] decodedData = Base64.getDecoder().decode(encryptedData);
// 解密数据。
byte[] decryptedData = cipher.doFinal(decodedData);
// 返回解密后的数据。
return new String(decryptedData, java.nio.charset.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);
}
}
运行结果:
加密后的数据: H+v+5je7lD1T5xZZC0kdqQ==
解密后的数据: Hello Dylan
AES 密钥更长,密钥空间更大,安全性更高,能有效抵抗暴力破解攻击。
当然,密钥长了,需要的存储空间也更多。
对称加密最大的问题是密钥管理。相比之下,非对称加密就没这个问题。
非对称加密:公钥加密,私钥解密,安全又灵活
非对称加密需要两把钥匙:公钥和私钥。
公钥和私钥是不同的,但它们是一对。用其中一把加密,就必须用另一把解密。比如,用公钥加密,就必须用私钥解密。
RSA:非对称加密的王者,应用广泛
RSA 算法是目前最流行的非对称加密算法。它由 Ron Rivest、Adi Shamir 和 Leonard Adleman 在 1978 年发明,名字就是用他们三个人的姓氏首字母组成的。
来看看 RSA 算法的 Java 实现:
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import javax.crypto.Cipher;
import java.util.Base64;
public class RSA {
// 公钥
private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7lEECdl7Jzh1uAfH3MOgLaWgiTq4FnxwE3NQjs8T00TmRRyKH9WyfFhIUlIkSgThXq5O+w2w8I8g10mWlYy8J0zv7Ghbsqhd/BdQHtq5GbGHm45IH4UkVjV8ymfA5RrHnkBKn45F30jZtJdrVsQgXqOVjtEqE5zS5RxYXtCZ93Zs8pgkGQOr05f4gGvTybTX1fKmZvWwpRYfpqywKm99XKts+0zm9f8yM4Wz92nMIpgQOaSFEllmMY8o0Yh7l2ibAz2mW5BbtHmJlGpVtjj04uE66Fhg0PUaBOuU3PqDnmFpn7BAdIRn6df4Wa4eyh9gKBkpy2z8XtyRhsBO3l4ecQvWsEjlRQzM0KgWQK37GnNyb0G9WwKHY9YoXzGqOeA1h8hzqPA9G9ITlDks+1Gwp6D54oyxjFhLC5uyz3seW5Fg99HqR91FZ1gFuXcQ==";
// 私钥
private static final String PRIVATE_KEY = "MIIEpAIBAAKCAQEA7lEECdl7Jzh1uAfH3MOgLaWgiTq4FnxwE3NQjs8T00TmRRyKH9WyfFhIUlIkSgThXq5O+w2w8I8g10mWlYy8J0zv7Ghbsqhd/BdQHtq5GbGHm45IH4UkVjV8ymfA5RrHnkBKn45F30jZtJdrVsQgXqOVjtEqE5zS5RxYXtCZ93Zs8pgkGQOr05f4gGvTybTX1fKmZvWwpRYfpqywKm99XKts+0zm9f8yM4Wz92nMIpgQOaSFEllmMY8o0Yh7l2ibAz2mW5BbtHmJlGpVtjj04uE66Fhg0PUaBOuU3PqDnmFpn7BAdIRn6df4Wa4eyh9gKBkpy2z8XtyRhsBO3l4ecQvWsEjlRQzM0KgWQK37GnNyb0G9WwKHY9YoXzGqOeA1h8hzqPA9G9ITlDks+1Gwp6D54oyxjFhLC5uyz3seW5Fg99HqR91FZ1gFuXcQ==";
/**
* 使用RSA公钥加密
*
* @param data 明文数据
* @return 加密后的数据
*/
public static String encrypt(String data) throws Exception {
// 获取公钥
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] keyBytes = Base64.getDecoder().decode(PUBLIC_KEY);
RSAPublicKey publicKey = (RSAPublicKey) keyFactory.generatePublic(new X509EncodedKeySpec(keyBytes));
// 使用RSA公钥加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedData = cipher.doFinal(data.getBytes());
return Base64.getEncoder().encodeToString(encryptedData);
}
/**
* 使用RSA私钥解密
*
* @param encryptedData 使用RSA公钥加密的数据
* @return 解密后的数据
*/
public static String decrypt(String encryptedData) throws Exception {
// 获取私钥
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
byte[] keyBytes = Base64.getDecoder().decode(PRIVATE_KEY);
RSAPrivateKey privateKey = (RSAPrivateKey) keyFactory.generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
// 使用RSA私钥解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decryptedData = cipher.doFinal(Base64.getDecoder().decode(encryptedData));
return new String(decryptedData);
}
public static void main(String[] args) throws Exception {
String data = "Hello RSA";
// 加密
String encryptedData = encrypt(data);
System.out.println("加密后的数据: " + encryptedData);
// 解密
String decryptedData = decrypt(encryptedData);
System.out.println("解密后的数据: " + decryptedData);
}
}
运行结果:
Encrypted data: kLKl+j90w34MwDu+k933znMxHnnajJeJCqIOfaYbiYT2IJrTmTisIGWvCJvtyprgMidObGxzhWAWs0lQKsq+dHZ70XG8m3ICMy4CxCYVdqOymEiSjD4HfEhKAZc58TDQ0J0qPdOpw+fqkmxsSG2sQmI87ffLx6ChbbuZlVrwJmm2KwuqWEwxuddilntsnZWLVn4uEXtHzHhrXm8RqOodVdLUemUxcV7N9x9v3DJyei7zZbTu2OEbija0bIHukQ9/yqZBbGSANfa8LVsQ+rsiKWd7+IGbPmsXmds8G6hgkkP1K2aHecOYgc8bo2vrY2httxadZzwqkknqn47eU+3cNg==
Decrypted data: Hello Dylan
RSA 的优点是安全性高。公钥可以随便公开,但私钥必须藏好,这样才能保证数据安全。它可以应用于数字签名、密钥协商等多种场景。
缺点是加密解密速度慢。密钥越长,加密解密的时间就越长。密钥太短容易被破解,密钥太长又会增加计算成本和存储空间。
加密算法选哪个?别挑花眼了!
今天我们简单回顾了五种常用的加密算法:对称加密算法(DES、AES)和非对称加密算法(RSA)。每种算法都有自己的特点和适用场景,但它们在加密效率、存储成本和计算开销等方面各有优劣。HTTPS 协议巧妙地结合了对称加密、非对称加密和哈希算法,大大提高了数据传输的安全性,确保了通信双方身份的真实性和数据的完整性。所以,理解和合理运用这些加密技术,对于保障互联网安全至关重要。
黑客/网络安全学习包
资料目录
成长路线图&学习规划
配套视频教程
SRC&黑客文籍
护网行动资料
黑客必读书单
面试题合集
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
*************************************CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************
1.成长路线图&学习规划
要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。
对于从来没有接触过网络安全的同学,我们帮你准备了详细的学习成长路线图&学习规划。可以说是最科学最系统的学习路线,大家跟着这个大的方向学习准没问题。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
*************************************CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************
2.视频教程
很多朋友都不喜欢晦涩的文字,我也为大家准备了视频教程,其中一共有21个章节,每个章节都是当前板块的精华浓缩。
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
*************************************CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*************************************
3.SRC&黑客文籍
大家最喜欢也是最关心的SRC技术文籍&黑客技术也有收录
SRC技术文籍:
黑客资料由于是敏感资源,这里不能直接展示哦!
4.护网行动资料
其中关于HW护网行动,也准备了对应的资料,这些内容可相当于比赛的金手指!
5.黑客必读书单
**
**
6.面试题合集
当你自学到这里,你就要开始思考找工作的事情了,而工作绕不开的就是真题和面试题。
更多内容为防止和谐,可以扫描获取~
因篇幅有限,仅展示部分资料,需要点击下方链接即可前往获取
*************************************CSDN大礼包:《黑客&网络安全入门&进阶学习资源包》免费分享*********************************