数字签名算法

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

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

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

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

常用的签名算法有

  • 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秒内即可破解。

 

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值