多语言网站如何做,网络建设方案论文,王湛,正规开网店咨询常见加密算法
加密算法是一种用数学方法对数据进行变换的技术#xff0c;目的是保护数据的安全#xff0c;防止被未经授权的人读取或修改。加密算法可以分为三大类#xff1a;对称加密算法、非对称加密算法和哈希算法#xff08;也叫摘要算法#xff09;。
哈希算法
哈…常见加密算法
加密算法是一种用数学方法对数据进行变换的技术目的是保护数据的安全防止被未经授权的人读取或修改。加密算法可以分为三大类对称加密算法、非对称加密算法和哈希算法也叫摘要算法。
哈希算法
哈希算法也叫哈希函数、散列函数或摘要算法它的作用是对任意长度的数据生成一个固定长度的唯一标识也叫哈希值、散列值或消息摘要后文统称为哈希值。 哈希值的作用是可以用来验证数据的完整性和一致性。
举两个实际的例子
我们下载一个文件时可以通过比较文件的哈希值和官方提供的哈希值是否一致来判断文件是否被篡改或损坏保存密码到数据库时使用哈希算法进行加密可以通过比较用户输入密码的哈希值和数据库保存的哈希值是否一致来判断密码是否正确。
这种算法的特点是不可逆
不能从哈希值还原出原始数据。原始数据的任何改变都会导致哈希值的巨大变化。
哈希算法主要下面几类
MDMessage Digest消息摘要算法比如 MD5。SHASecure Hash Algorithm安全哈希算法比如 SHA-1、SHA-256。MACMessage Authentication Code消息认证码算法比如 HMAC(Hash Message Authentication Code)。其他国密算法SM3、密码哈希算法Bcrypt。
国密算法常见的如 SM2、SM3、SM4其中 SM2 为非对称加密算法SM4 为对称加密算法SM3 为哈希算法安全性及效率和 SHA-256 相当但更适合国内的应用环境。
哈希算法一般是不需要密钥的但也存在部分特殊哈希算法需要密钥。例如MAC 算法就是一种基于密钥的哈希算法它在哈希算法的基础上增加了一个密钥使得只有知道密钥的人才能验证数据的完整性和来源。
MD
MD 算法有多个版本包括 MD2、MD4、MD5 等其中 MD5 是最常用的版本它可以生成一个 128 位16 字节的哈希值。从安全性上说MD5 MD4 MD2。除了这些版本还有一些基于 MD4 或 MD5 改进的算法如 RIPEMD、HAVAL 等。
即使是最安全 MD 算法 MD5 也存在被破解的风险攻击者可以通过暴力破解或彩虹表攻击等方式找到与原始数据相同的哈希值从而破解数据。
为了增加破解难度通常可以选择加盐。盐Salt在密码学中是指通过在密码任意固定位置插入特定的字符串让哈希后的结果和使用原始密码的哈希结果不相符这种过程称之为“加盐”。
加盐之后就安全了吗并不一定这只是增加了破解难度不代表无法破解。而且MD5 算法本身就存在弱碰撞Collision问题即多个不同的输入产生相同的 MD5 值。
因此MD 算法已经不被推荐使用建议使用更安全的哈希算法比如 SHA-2、Bcrypt。
Java 提供了对 MD 算法系列的支持包括 MD2、MD5。
MD5 代码示例未加盐
String originalString Java学习 面试指南javaguide.cn;
// 创建MD5摘要对象
MessageDigest messageDigest MessageDigest.getInstance(MD5);
messageDigest.update(originalString.getBytes(StandardCharsets.UTF_8));
// 计算哈希值
byte[] result messageDigest.digest();
// 将哈希值转换为十六进制字符串
String hexString new HexBinaryAdapter().marshal(result);
System.out.println(Original String: originalString);
System.out.println(SHA-256 Hash: hexString.toLowerCase());SHA
SHASecure Hash Algorithm系列算法是一组密码哈希函数用于将任意长度的数据映射为固定长度的哈希值。SHA 系列算法由美国国家安全局NSA于 1993 年设计目前共有 SHA-1、SHA-2、SHA-3 三种版本。
SHA-1 算法将任意长度的数据映射为 160 位的哈希值。然而SHA-1 算法存在一些严重的缺陷比如安全性低容易受到碰撞攻击和长度扩展攻击。因此SHA-1 算法已经不再被推荐使用。 SHA-2 家族如 SHA-256、SHA-384、SHA-512 等和 SHA-3 系列是 SHA-1 算法的替代方案它们都提供了更高的安全性和更长的哈希值长度。
SHA-2 家族是在 SHA-1 算法的基础上改进而来的它们采用了更复杂的运算过程和更多的轮次使得攻击者更难以通过预计算或巧合找到碰撞。
为了寻找一种更安全和更先进的密码哈希函数美国国家标准与技术研究院National Institute of Standards and Technology简称 NIST在 2007 年公开征集 SHA-3 的候选算法。NIST 一共收到了 64 个算法方案经过多轮的评估和筛选最终在 2012 年宣布 Keccak 算法胜出成为 SHA-3 的标准算法SHA-3 与 SHA-2 算法没有直接的关系。 Keccak 算法具有与 MD 和 SHA-1/2 完全不同的设计思路即海绵结构Sponge Construction使得传统攻击方法无法直接应用于 SHA-3 的攻击中能够抵抗目前已知的所有攻击方式包括碰撞攻击、长度扩展攻击、差分攻击等。
由于 SHA-2 算法还没有出现重大的安全漏洞而且在软件中的效率更高所以大多数人还是倾向于使用 SHA-2 算法。
相比 MD5 算法SHA-2 算法之所以更强主要有两个原因
哈希值长度更长例如 SHA-256 算法的哈希值长度为 256 位而 MD5 算法的哈希值长度为 128 位这就提高了攻击者暴力破解或者彩虹表攻击的难度。更强的碰撞抗性SHA 算法采用了更复杂的运算过程和更多的轮次使得攻击者更难以通过预计算或巧合找到碰撞。目前还没有找到任何两个不同的数据它们的 SHA-256 哈希值相同。
当然SHA-2 也不是绝对安全的也有被暴力破解或者彩虹表攻击的风险所以在实际的应用中加盐还是必不可少的。
Java 提供了对 SHA 算法系列的支持包括 SHA-1、SHA-256、SHA-384 和 SHA-512。
SHA-256 代码示例未加盐
String originalString Java学习 面试指南javaguide.cn;
// 创建SHA-256摘要对象
MessageDigest messageDigest MessageDigest.getInstance(SHA-256);
messageDigest.update(originalString.getBytes());
// 计算哈希值
byte[] result messageDigest.digest();
// 将哈希值转换为十六进制字符串
String hexString new HexBinaryAdapter().marshal(result);
System.out.println(Original String: originalString);
System.out.println(SHA-256 Hash: hexString.toLowerCase());Bcrypt
Bcrypt 算法是一种基于 Blowfish 加密算法的密码哈希函数专门为密码加密而设计安全性高。
由于 Bcrypt 采用了 salt盐 和 cost成本 两种机制它可以有效地防止彩虹表攻击和暴力破解攻击从而保证密码的安全性。salt 是一个随机生成的字符串用于和密码混合增加密码的复杂度和唯一性。cost 是一个数值参数用于控制 Bcrypt 算法的迭代次数增加密码哈希的计算时间和资源消耗。
Bcrypt 算法可以根据实际情况进行调整加密的复杂度可以设置不同的 cost 值和 salt 值从而满足不同的安全需求灵活性很高。
Java 应用程序的安全框架 Spring Security 支持多种密码编码器其中 BCryptPasswordEncoder 是官方推荐的一种它使用 BCrypt 算法对用户的密码进行加密存储。
Bean
public PasswordEncoder passwordEncoder(){return new BCryptPasswordEncoder();
}对称加密
对称加密算法是指加密和解密使用同一个密钥的算法也叫共享密钥加密算法。 常见的对称加密算法有 DES、3DES、AES 等。
DES 和 3DES
DESData Encryption Standard使用 64 位的密钥(有效秘钥长度为 56 位,8 位奇偶校验位)和 64 位的明文进行加密。
虽然 DES 一次只能加密 64 位但我们只需要把明文划分成 64 位一组的块就可以实现任意长度明文的加密。如果明文长度不是 64 位的倍数必须进行填充常用的模式有 PKCS5Padding, PKCS7Padding, NOPADDING。
DES 加密算法的基本思想是将 64 位的明文分成两半然后对每一半进行多轮的变换最后再合并成 64 位的密文。这些变换包括置换、异或、选择、移位等操作每一轮都使用了一个子密钥而这些子密钥都是由同一个 56 位的主密钥生成的。DES 加密算法总共进行了 16 轮变换最后再进行一次逆置换得到最终的密文。 这是一个经典的对称加密算法但也有明显的缺陷即 56 位的密钥安全性不足已被证实可以在短时间内破解。
为了提高 DES 算法的安全性人们提出了一些变种或者替代方案例如 3DESTriple DES。
3DESTriple DES是 DES 向 AES 过渡的加密算法它使用 2 个或者 3 个 56 位的密钥对数据进行三次加密。3DES 相当于是对每个数据块应用三次 DES 的对称加密算法。
为了兼容普通的 DES3DES 并没有直接使用 加密-加密-加密 的方式而是采用了加密-解密-加密 的方式。当三种密钥均相同时前两步相互抵消相当于仅实现了一次加密因此可实现对普通 DES 加密算法的兼容。3DES 比 DES 更为安全但其处理速度不高。
AES
AESAdvanced Encryption Standard算法是一种更先进的对称密钥加密算法它使用 128 位、192 位或 256 位的密钥对数据进行加密或解密密钥越长安全性越高。
AES 也是一种分组(或者叫块)密码分组长度只能是 128 位也就是说每个分组为 16 个字节。AES 加密算法有多种工作模式mode of operation如ECB、CBC、OFB、CFB、CTR、XTS、OCB、GCM目前使用最广泛的模式。不同的模式参数和加密流程不同但是核心仍然是 AES 算法。
和 DES 类似对于不是 128 位倍数的明文需要进行填充常用的填充模式有 PKCS5Padding, PKCS7Padding, NOPADDING。不过AES-GCM 是流加密算法可以对任意长度的明文进行加密所以对应的填充模式为 NoPadding即无需填充。
AES 的速度比 3DES 快而且更安全。 DES 算法和 AES 算法简单对比图片来自于RSA vs. AES Encryption: Key Differences Explainedopen in new window 基于 Java 实现 AES 算法代码示例
private static final String AES_ALGORITHM AES;
// AES密钥
private static final String AES_SECRET_KEY 4128D9CDAC7E2F82951CBAF7FDFE675B;
// AES加密模式为GCM填充方式为NoPadding
// AES-GCM 是流加密Stream cipher算法所以对应的填充模式为 NoPadding即无需填充。
private static final String AES_TRANSFORMATION AES/GCM/NoPadding;
// 加密器
private static Cipher encryptionCipher;
// 解密器
private static Cipher decryptionCipher;/*** 完成一些初始化工作*/
public static void init() throws Exception {// 将AES密钥转换为SecretKeySpec对象SecretKeySpec secretKeySpec new SecretKeySpec(AES_SECRET_KEY.getBytes(), AES_ALGORITHM);// 使用指定的AES加密模式和填充方式获取对应的加密器并初始化encryptionCipher Cipher.getInstance(AES_TRANSFORMATION);encryptionCipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);// 使用指定的AES加密模式和填充方式获取对应的解密器并初始化decryptionCipher Cipher.getInstance(AES_TRANSFORMATION);decryptionCipher.init(Cipher.DECRYPT_MODE, secretKeySpec, new GCMParameterSpec(128, encryptionCipher.getIV()));
}/*** 加密*/
public static String encrypt(String data) throws Exception {byte[] dataInBytes data.getBytes();// 加密数据byte[] encryptedBytes encryptionCipher.doFinal(dataInBytes);return Base64.getEncoder().encodeToString(encryptedBytes);
}/*** 解密*/
public static String decrypt(String encryptedData) throws Exception {byte[] dataInBytes Base64.getDecoder().decode(encryptedData);// 解密数据byte[] decryptedBytes decryptionCipher.doFinal(dataInBytes);return new String(decryptedBytes, StandardCharsets.UTF_8);
}public static void main(String[] args) throws Exception {String originalString Java学习 面试指南javaguide.cn;init();String encryptedData encrypt(originalString);String decryptedData decrypt(encryptedData);System.out.println(Original String: originalString);System.out.println(AES Encrypted Data : encryptedData);System.out.println(AES Decrypted Data : decryptedData);
}非对称加密
非对称加密算法是指加密和解密使用不同的密钥的算法也叫公开密钥加密算法。这两个密钥互不相同一个称为公钥另一个称为私钥。公钥可以公开给任何人使用私钥则要保密。
如果用公钥加密数据只能用对应的私钥解密加密如果用私钥加密数据只能用对应的公钥解密签名。这样就可以实现数据的安全传输和身份认证。 常见的非对称加密算法有 RSA、DSA、ECC 等。
RSA
RSARivest–Shamir–Adleman algorithm算法是一种基于大数分解的困难性的非对称加密算法它需要选择两个大素数作为私钥的一部分然后计算出它们的乘积作为公钥的一部分寻求两个大素数比较简单而将它们的乘积进行因式分解却极其困难。
RSA 算法的安全性依赖于大数分解的难度目前已经有 512 位和 768 位的 RSA 公钥被成功分解因此建议使用 2048 位或以上的密钥长度。
RSA 算法的优点是简单易用可以用于数据加密和数字签名缺点是运算速度慢不适合大量数据的加密。
RSA 算法是是目前应用最广泛的非对称加密算法像 SSL/TLS、SSH 等协议中就用到了 RSA 算法。
基于 Java 实现 RSA 算法代码示例
private static final String RSA_ALGORITHM RSA;/*** 生成RSA密钥对*/
public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {KeyPairGenerator keyPairGenerator KeyPairGenerator.getInstance(RSA_ALGORITHM);// 密钥大小为2048位keyPairGenerator.initialize(2048);return keyPairGenerator.generateKeyPair();
}/*** 使用公钥加密数据*/
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);
}/*** 使用私钥解密数据*/
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 originalString Java学习 面试指南javaguide.cn;String encryptedData encrypt(originalString, publicKey);String decryptedData decrypt(encryptedData, privateKey);System.out.println(Original String: originalString);System.out.println(RSA Encrypted Data : encryptedData);System.out.println(RSA Decrypted Data : decryptedData);
}DSA
DSADigital Signature Algorithm算法是一种基于离散对数的困难性的非对称加密算法它需要选择一个素数 q 和一个 q 的倍数 p 作为私钥的一部分然后计算出一个模 p 的原根 g 和一个模 q 的整数 y 作为公钥的一部分。DSA 算法的安全性依赖于离散对数的难度目前已经有 1024 位的 DSA 公钥被成功破解因此建议使用 2048 位或以上的密钥长度。
DSA 算法的优点是数字签名速度快适合生成数字证书缺点是不能用于数据加密且签名过程需要随机数。
DSA 算法签名过程
使用消息摘要算法对要发送的数据进行加密生成一个信息摘要也就是一个短的、唯一的、不可逆的数据表示。发送方用自己的 DSA 私钥对信息摘要再进行加密形成一个数字签名也就是一个可以证明数据来源和完整性的数据附加。将原始数据和数字签名一起通过互联网传送给接收方。接收方用发送方的公钥对数字签名进行解密得到信息摘要。同时接收方也用消息摘要算法对收到的原始数据进行加密得到另一个信息摘要。接收方将两个信息摘要进行比较如果两者一致则说明在传送过程中数据没有被篡改或损坏否则则说明数据已经失去了安全性和保密性。 作者声明
如有问题欢迎指正