刚接触密码学的时候,我常常把哈希算法和数字签名算法搞混 以为数字签名算法的类型就是哈希算法 结果这两个不是一个东西
一、相同点
1、数据完整性验证
-
哈希算法:通过生成固定长度的哈希值,验证数据是否被篡改。
-
数字签名算法:通过生成数字签名,验证数据的完整性和来源真实性
JAVA示例
// 哈希算法示例
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest("data".getBytes());
// 数字签名算法示例
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(privateKey);
signature.update("data".getBytes());
byte[] digitalSignature = signature.sign();
2、不可逆性
-
哈希算法:哈希值无法还原为原始数据。
-
数字签名算法:签名无法还原为原始数据或私钥。
-
Java 示例:
-
哈希值无法通过逆向操作还原数据。
-
数字签名无法通过公钥还原私钥或原始数据。
-
3、唯一性
-
哈希算法:相同输入生成相同哈希值。
-
数字签名算法:相同数据和私钥生成相同签名。
JAVA示例
// 哈希算法
byte[] hash1 = md.digest("data".getBytes());
byte[] hash2 = md.digest("data".getBytes());
assert Arrays.equals(hash1, hash2); // 相同输入生成相同哈希值
// 数字签名算法
signature.update("data".getBytes());
byte[] signature1 = signature.sign();
signature.update("data".getBytes());
byte[] signature2 = signature.sign();
assert Arrays.equals(signature1, signature2); // 相同输入生成相同签名
二、不同点
1、功能目标
-
哈希算法:主要用于数据完整性校验(如文件校验、密码存储)。
-
数字签名算法:用于身份认证和数据完整性校验(如电子签名、证书验证)。
JAVA示例
- 哈希算法常用于密码存储:
String password = "user123";
byte[] hash = md.digest(password.getBytes());
- 数字签名算法用于验证数据来源:
signature.initVerify(publicKey);
signature.update("data".getBytes());
boolean verified = signature.verify(digitalSignature);
2、密钥使用
-
哈希算法:不需要密钥。
-
数字签名算法:需要密钥对(私钥签名,公钥验证)。
Java 示例:
- 哈希算法无需密钥:
MessageDigest md = MessageDigest.getInstance("SHA-256");
- 数字签名算法需要密钥:
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
KeyPair keyPair = keyGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
3、输入与输出
-
哈希算法:输入为任意长度数据,输出为固定长度哈希值。
-
数字签名算法:输入为数据和私钥,输出为数字签名。
Java 示例:
- 哈希算法:
byte[] hash = md.digest("data".getBytes()); // 输出固定长度哈希值
- 数字签名算法:
signature.initSign(privateKey);
signature.update("data".getBytes());
byte[] digitalSignature = signature.sign(); // 输出数字签名
4、算法复杂度
-
哈希算法:计算速度快,适合大数据量处理。
-
数字签名算法:计算速度较慢,适合小数据量签名。
5、应用场景
-
哈希算法:密码存储、文件校验、数据去重。
-
数字签名算法:电子签名、SSL/TLS 证书、数字证书验证。
Java 支持的哈希算法
Java 通过 MessageDigest 类支持多种哈希算法,常见的包括:
-
MD5(不推荐,安全性低)
-
SHA-1(不推荐,安全性低)
-
SHA-256
-
SHA-384
-
SHA-512
示例
MessageDigest md = MessageDigest.getInstance("SHA-256");
byte[] hash = md.digest("data".getBytes());
Java 支持的数字签名算法
Java 通过 Signature 类支持多种数字签名算法,常见的包括:
-
SHA1withRSA
-
SHA256withRSA
-
SHA512withRSA
-
SHA256withECDSA(基于椭圆曲线)
// 生成密钥对
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(2048);
KeyPair keyPair = keyGen.generateKeyPair();
// 签名
Signature signature = Signature.getInstance("SHA256withRSA");
signature.initSign(keyPair.getPrivate());
signature.update("data".getBytes());
byte[] digitalSignature = signature.sign();
// 验证
signature.initVerify(keyPair.getPublic());
signature.update("data".getBytes());
boolean verified = signature.verify(digitalSignature);
总结
特性 哈希算法 数字签名算法
功能 数据完整性校验 数据完整性校验 + 身份认证
密钥使用 无需密钥 需要密钥对(私钥签名,公钥验证)
输出 固定长度哈希值 数字签名
速度 快 较慢
应用场景 密码存储、文件校验 电子签名、证书验证
在 Java 中,哈希算法通过 MessageDigest 类实现,数字签名算法通过 Signature 类实现。两者结合使用可以提供更全面的数据安全保障。