数字签名算法
近期闲来无聊,也研究下一些基础的东西。
什么是数字签名,它的作用
带有**(公钥,私钥)的消息摘要算法,用于验证数据完整性,认证数据来源,抗否认
通俗来讲就是证明某个消息或者文件是本人发出/认同的,这个的话用于的面就比较多了。比如电子合同,银行签约,电子授权等等。所以他的安全性是我们必须要考虑的。
常用的签名算法有
- RSA,基于大整数分解问题
- DSA,基于离散对数问题
- ECDSA也叫椭圆加密算法,属于DSA的一个变种,基于椭圆曲线上的离散对数问题
RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对**,使用其中一个加密,则需要用另一个才能解密。。 这里我就直接写下RSA加密算法基于jdk实现。
其实就是私钥加密和公钥解密的过程
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import org.apache.commons.codec.binary.Hex;
/**
* 基于jdk实现
*
*/
public class TestRSA {
public static void main(String[] args) {
doRSA();
}
public static void doRSA() {
try {
String src = "test rsa signature";
//1.初始化**
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
keyPairGenerator.initialize(512);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//生成公钥
RSAPublicKey rsaPublicKey = (RSAPublicKey)keyPair.getPublic();
//生成私钥
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)keyPair.getPrivate();
//2.执行签名
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(rsaPrivateKey.getEncoded());
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
//签名
Signature signature = Signature.getInstance("MD5withRSA");
//用私钥进行签名
signature.initSign(privateKey);
//签名的内容
signature.update(src.getBytes());
byte[] result = signature.sign();
System.out.println("jdk rsa sign : " + Hex.encodeHexString(result));
//3.验证签名
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(rsaPublicKey.getEncoded());
keyFactory = KeyFactory.getInstance("RSA");
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
signature = Signature.getInstance("MD5withRSA");
//用公钥进行验证
signature.initVerify(publicKey);
//验证的内容
signature.update(src.getBytes());
boolean bool = signature.verify(result);
System.out.println("jdk rsa verify : " + bool);
} catch (Exception e) {
e.printStackTrace();
}
}
}
安全性来说的话也是比较高的,当然也是可以**的。我们还有其他两种算法。
已公开的或已知的攻击方法
1,针对RSA最流行的攻击一般是基于大数因数分解。1999年,RSA-155 (512 bits)被成功分解,花了五个月时间(约8000 MIPS年)和224 CPU hours在一台有3.2G*内存的Cray C916计算机上完成。
RSA-158表示如下:
1 |
|
2009年12月12日,编号为RSA-768(768 bits, 232 digits)数也被成功分解。这一事件威胁了现通行的1024-bit**的安全性,普遍认为用户应尽快升级到2048-bit或以上。 [1]
RSA-768表示如下:
1 |
|
2,秀尔算法
量子计算里的秀尔算法能使穷举的效率大大的提高。由于RSA算法是基于大数分解(无法抵抗穷举攻击),因此在未来量子计算能对RSA算法构成较大的威胁。一个拥有N量子比特的量子计算机,每次可进行2^N次运算,理论上讲,**为1024位长的RSA算法,用一台512量子比特位的量子计算机在1秒内即可**。
我没有深入去研究他的实现了,只要知道这几种签名是用私钥加密,公钥解密这些基本就够了。如果你感兴趣可以继续研究下去,兴趣才是最好的老师。