簽名算法
私鑰加密得到的密文實際上就是數字簽名,要驗證這個簽名是否正確,只能用私鑰持有者的公鑰進行解密驗證。使用數字簽名的目的是為了確認某個信息確實是由某個發送方發送的,任何人都不可能偽造消息,並且,發送方也不能抵賴。
在實際應用的時候,簽名實際上並不是針對原始消息,而是針對原始消息的哈希進行簽名,對簽名進行驗證實際上就是用公鑰解密,然后把解密后的哈希與原始消息的哈希進行對比。
因為用戶總是使用自己的私鑰進行簽名,所以,私鑰就相當於用戶身份。而公鑰用來給外部驗證用戶身份。
常用數字簽名算法有:
- MD5withRSA
- SHA1withRSA
- SHA256withRSA
它們實際上就是指定某種哈希算法進行RSA簽名的方式。
public class TestDemo { public static void main(String[] args) throws Exception { // 生成RSA公鑰/私鑰 KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA"); kpGen.initialize(1024); KeyPair kp = kpGen.generateKeyPair(); PrivateKey sk = kp.getPrivate(); PublicKey pk = kp.getPublic(); // 待簽名的消息: byte[] message = "Hello, World!".getBytes(StandardCharsets.UTF_8); // 用私鑰簽名: Signature s = Signature.getInstance("SHA1withRSA"); s.initSign(sk); s.update(message); byte[] signed = s.sign(); System.out.println(String.format("signature: %x", new BigInteger(1, signed))); // 用公鑰驗證: Signature v = Signature.getInstance("SHA1withRSA"); v.initVerify(pk); v.update(message); boolean valid = v.verify(signed); System.out.println("valid: " + valid); } }
DSA簽名
除了RSA可以簽名外,還可以使用DSA算法進行簽名。DSA是Digital Signature Algorithm的縮寫,它使用ElGamal數字簽名算法。
DSA只能配合SHA使用,常用的算法有:
- SHA1withDSA
- SHA256withDSA
- SHA512withDSA
和RSA數字簽名相比,DSA的優點是更快。
ECDSA簽名
橢圓曲線簽名算法ECDSA:Elliptic Curve Digital Signature Algorithm也是一種常用的簽名算法,它的特點是可以從私鑰推出公鑰。比特幣的簽名算法就采用了ECDSA算法,使用標准橢圓曲線secp256k1。BouncyCastle提供了ECDSA的完整實現。
總結:
數字簽名就是用發送方的私鑰對原始數據進行簽名,只有用發送方公鑰才能通過簽名驗證。
數字簽名用於:
- 防止偽造;
- 防止抵賴;
- 檢測篡改。
常用的數字簽名算法包括:MD5withRSA/SHA1withRSA/SHA256withRSA/SHA1withDSA/SHA256withDSA/SHA512withDSA/ECDSA等。