欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

数字签名算法

程序员文章站 2022-07-09 11:50:35
...

近期闲来无聊,也研究下一些基础的东西。

什么是数字签名,它的作用

带有**(公钥,私钥)的消息摘要算法,用于验证数据完整性,认证数据来源,抗否认

通俗来讲就是证明某个消息或者文件是本人发出/认同的,这个的话用于的面就比较多了。比如电子合同,银行签约,电子授权等等。所以他的安全性是我们必须要考虑的。

常用的签名算法有

  • 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

395058745832651445264197678006144819960207764603049364541393760515793556265294506836097278424682195350935443058704902519956553357102097992264849779494429556033388495837466721394368393204672181522815830368604993048084925840555281177×  11658823406671259903148376558383270818131012258146392600439520994131344334162924536139

2009年12月12日,编号为RSA-768(768 bits, 232 digits)数也被成功分解。这一事件威胁了现通行的1024-bit**的安全性,普遍认为用户应尽快升级到2048-bit或以上。 [1] 

RSA-768表示如下:

1

12301866845301177551304949583849627207728535695953347921973224521517264005072636575187452021997864693899564749427740638459251925573263034537315482685079170261221429134616704292143116022212404792747377940806653514195974598569021434133347807169895689878604416984821269081770479498371376856891  2431388982883793878002287614711652531743087737814467999489×  3674604366679959042824463379962795263227915816434308764267  6032283815739666511279233373417143396810270092798736308917

2,秀尔算法

量子计算里的秀尔算法能使穷举的效率大大的提高。由于RSA算法是基于大数分解(无法抵抗穷举攻击),因此在未来量子计算能对RSA算法构成较大的威胁。一个拥有N量子比特的量子计算机,每次可进行2^N次运算,理论上讲,**为1024位长的RSA算法,用一台512量子比特位的量子计算机在1秒内即可**。

 

我没有深入去研究他的实现了,只要知道这几种签名是用私钥加密,公钥解密这些基本就够了。如果你感兴趣可以继续研究下去,兴趣才是最好的老师。

上一篇: 数字签名

下一篇: 七、数字签名