十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

盘点 5 种常用加密算法!

盘点 5 种常用加密算法! 支付常常要和一些加签、验签加密、解密打交道今天就给大家来盘点一下最常见的5种加密算法。前言大家平时的工作中可能也在很多地方用到了加密、解密比如用户的密码不能明文存储要存储加密后的密文用户的银行卡号、身份证号之类的敏感数据需要加密传输还有一些重要接口比如支付客户端要对请求生成一个签名服务端要对签名进行验证……非常安全那么上面提到的这些能力我们都可以利用哪些加密算法来实现呢咱们接着往下看。常见加密算法算法整体上可以分为不可逆加密以及可逆加密可逆加密又可以分为对称加密和非对称加密。加密算法分类不可逆算法不可逆加密的算法的加密是不可逆的密文无法被还原成原文。散列算法就是一种不可逆算法。散列算法中明文通过散列算法生成散列值散列值是长度固定的数据和明文长度无关。散列算法散列算法的具体实现有很多种常见的包括MD5、SHA1、SHA-224、SHA-256等等。散列算法常用于数字签名、消息认证、密码存储等场景。散列算法是不需要密钥的当然也有一些不可逆算法需要密钥例如HMAC算法。MD5MD5全称为“Message-Digest Algorithm 5”翻译过来叫“信息摘要算法”。它可以将任意长度的数据通过散列算法生成一个固定长度的散列值。MD5算法的输出长度为128位通常用32个16进制数表示。我们来看下MD5算法的Java代码实现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); } }MD5有一些优点比如计算速度快、输出长度固定、应用广泛等等。但是作为一个加密算法它有一个天大的缺点那就是不安全。MD5算法已经被攻破而且MD5算法的输出长度有限攻击者可以通过暴力破解或彩虹表攻击等方式找到与原始数据相同的散列值从而破解数据。虽然可以通过加盐也就是对在原文里再加上一些不固定的字符串来缓解但是完全可以用更安全的SHA系列算法替代。SHA-256SHASecure Hash Algorithm系列算法是一组密码散列函数用于将任意长度的数据映射为固定长度的散列值。SHA系列算法由美国国家安全局NSA于1993年设计目前共有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代码实现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算法采用了更复杂的运算过程和更多的轮次使得攻击者更难以通过预计算或巧合找到碰撞。当然SHA-2也不是绝对安全的散列算法都有被暴力破解或者彩虹表攻击的风险所以在实际的应用中加盐还是必不可少的。加盐对称加密算法对称加密算法使用同一个密钥进行加密和解密。对称加密算法加密和解密过程使用的是相同的密钥因此密钥的安全性至关重要。如果密钥泄露攻击者可以轻易地破解加密数据。常见的对称加密算法包括DES、3DES、AES等。其中AES算法是目前使用最广泛的对称加密算法之一具有比较高的安全性和加密效率。DESDESData Encryption Standard算法是一种对称加密算法由IBM公司于1975年研发是最早的一种广泛应用的对称加密算法之一。DES算法使用56位密钥对数据进行加密加密过程中使用了置换、替换、异或等运算具有较高的安全性。我们来看下DES算法的Java代码实现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); } }DES的算法速度较快但是在安全性上面并不是最优选择因为DES算法的密钥长度比较短被暴力破解和差分攻击的风险比较高一般推荐用一些更安全的对称加密算法比如3DES、AES。AESAESAdvanced Encryption Standard即高级加密标准是一种对称加密算法被广泛应用于数据加密和保护领域。AES算法使用的密钥长度为128位、192位或256位比DES算法的密钥长度更长安全性更高。我们来看下AES算法的Java代码实现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); } }AES算法采用的密钥长度更长密钥空间更大安全性更高能够有效地抵抗暴力破解攻击。当然因为密钥长度较长需要的存储也更多。对于对称加密算法而言最大的痛点就在于密钥管理困难相比而言非对称加密就没有这个担忧。非对称加密算法非对称加密算法需要两个密钥这两个密钥互不相同但是相互匹配一个称为公钥另一个称为私钥。使用其中的一个加密则使用另一个进行解密。例如使用公钥加密则需要使用私钥解密。公钥加密私钥解密RSARSA算法是是目前应用最广泛的非对称加密算法由Ron Rivest、Adi Shamir和Leonard Adleman三人在1978年发明名字来源三人的姓氏首字母。我们看下RSA算法的Java实现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算法的优点是安全性高公钥可以公开私钥必须保密保证了数据的安全性可用于数字签名、密钥协商等多种应用场景。缺点是加密、解密速度较慢密钥长度越长加密、解密时间越长密钥长度过短容易被暴力破解密钥长度过长则会增加计算量和存储空间的开销。总结这一期就给大家简单盘点了一下最常用的5种加密算法。其实论到加密解密算法的应用有一个东西可以说是应用到了极致它是什么呢——HTTPShttps工作流程详图我们简单回忆一下HTTPS的工作流程和用到的加密算法客户端发起HTTPS请求用户使用浏览器输入网址访问HTTPS站点准备发起HTTPS请求服务端提供证书服务器返回公钥证书证书包含了服务器的公钥、颁发者证书颁发机构等信息客户端验证证书浏览器验证证书的有效性、合法性、来源等校验证书的过程用到了非对称加密和散列算法客户端使用证书颁发机构的公钥对证书进行验证保证证书的真实性和合法性客户端使用证书中的公钥对服务端的数字签名进行验证保证服务器的身份和数据的完整性。客户端使用散列算法计算出散列值和证书种的散列值进行对比保证证书的完整性客户端生成对称密钥客户端生成一个随机数作为对称密钥对称密钥加密传输客户端使用服务器的公钥对随机数进行加密然后将加密后的信息传输给服务器服务端获取对称密钥服务端使用私钥解密客户端发送的对称密钥得到对称密钥客户端与服务器使用对称密钥进行通信服务器与浏览器都使用对称密钥对数据进行加密和解密以此确保数据传输的安全性。在数据传输的过程中也用到了散列算法消息摘要在数据传输过程中客户端和服务器都使用散列算法计算消息的散列值对方收到消息后会对散列值进行比较确保传输数据的完整性。总之HTTPS使用了对称加密算法、非对称加密算法、散列算法来保证数据的安全性和完整性从而确保了通信双方的身份和数据的安全。https真吊至于具体使用哪些加密算法取决于SSL/TLS协议的版本以及协商过程中选定的加密套件。在实际的网络环境中很多加密算法可能会被淘汰以适应更高安全性的需要。在我们的日常开发中也可以借鉴相应的思路灵活运用各种加密算法让我们的应用更加安全、更加健壮。
返回列表