实验报告一、实验目的理解DSA算法原理二、实验内容与设计思想数字签名是一种以电子形式给消息签名的方法,是只有信息发送方才能进行的签名、信息发送方进行签名后将产生一段任何人都无法伪造的字符串,这段特殊的字符串同时也是对签名真实性的一种证明。
电子信息在传输过程中,通过数字签名达到与传统手写签名相同的效果。
数字签名的实现原理简单地说,就是发送方利用hash算法对要传送的信息计算得到一个固定长度的消息摘要值,用发送方的私钥加密此消息的hash值所生成的密文即数字签名;然后将数字签名和消息一同发送给接收方。
接收方收到消息和数字签名后,用同样的hash算法对消息进行计算,得到新的hash值,再用发送方的公钥对数字签名解密,将解密后的结果与新的hash值比较,如果相等则说明消息确实来自发送方。
DSA(Digital Signature Algorithm)源于ElGamal和Schnorr签名算法,1991年被美国NIST采纳为数字签名标准DSS(Digital Signature Standard),具体实现过程参见图1。
DSS安全性基于有限域求离散对数的困难性,算法描述如下:1.密钥生成算法1)选取160比特长的素数q和L比特长的素数p,满足q|(p−1),其中L≡0(mod 64)且512≤L≤1024;2)随机选取正整数h,1<h<(p-1),令g=h(p−1)/q mod p>1;q,p和g作为系统公开参数;3)每个用户,随机选取正整数x,1≤x≤q−1,计算y=g x mod p;用户的公钥为y,私钥为x。
2.签名算法对于消息M,首先随机选取整数k,1≤k≤p−2,计算r=(g k mod p) mod qs=(H(M)+xr)k−1mod q则M的签名为(r,s),其中H为Hash函数SHA。
3.验证算法接收方收到消息M′和签名(r′,s′)后,计算e1=H(M′)s′−1mod qe2=r′s′−1mod q验证等式(g e1y e2mod p) mod q如果v=r′成立,则说明消息确实来自发送方。
三、DSA算法实验步骤和调试过程(建议画出程序流程图)(1)编码实现DSA算法,源代码如下:package Demo;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.DSAPrivateKey;import java.security.interfaces.DSAPublicKey;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import javax.xml.bind.DatatypeConverter;public class DSA {p rivate static String src = "I LOVE CHINA.";p ublic static void main(String[] args) {jdkDSA();}p ublic static void jdkDSA() {// 1. 初始化秘钥try {KeyPairGenerator generator = KeyPairGenerator.getInstance("DSA");generator.initialize(512);KeyPair keyPair = generator.generateKeyPair();DSAPublicKey dsaPublicKey = (DSAPublicKey) keyPair.getPublic();DSAPrivateKey dsaPrivateKey = (DSAPrivateKey) keyPair.getPrivate();System.out.println("public="+dsaPublicKey);// System.out.println("private="+dsaPrivateKey.getParams());System.out.println("x="+dsaPrivateKey.getX());// 2。
执行签名PKCS8EncodedKeySpec pkcs8EncodedKeySpec= new PKCS8EncodedKeySpec(dsaPrivateKey.getEncoded());KeyFactory factory = KeyFactory.getInstance("DSA");PrivateKey privateKey = factory.generatePrivate(pkcs8EncodedKeySpec);Signature signature = Signature.getInstance("SHA1withDSA");signature.initSign(privateKey);signature.update(src.getBytes());byte[] sign = signature.sign();S ystem.out.println("sign=\n"+DatatypeConverter.printHexBinary(sign));// 验证签名X509EncodedKeySpec x509EncodedKeySpec= new X509EncodedKeySpec(dsaPublicKey.getEncoded());factory = KeyFactory.getInstance("DSA");PublicKey publicKey = factory.generatePublic(x509EncodedKeySpec);signature = Signature.getInstance("SHA1withDSA");signature.initVerify(publicKey);signature.update(src.getBytes());(2)DSA签名①选取密钥q= 962eddcc 369cba8e bb260ee6 b6a126d9 346e38c5,p= fca682ce 8e12caba 26efccf7 110e526d b078b05e decbcd1e b4a208f3 ae1617ae 01f35b91 a47e6df6 3413c5e1 2ed0899b cd132acd 50d99151 bdc43ee7 37592e17,g= 678471b2 7a9cf44e e91a49c5 147db1a9 aaf244f0 5a434d64 86931d2d 14271b9e35030b71 fd73da17 9069b32e 2935630e 1c206235 4d0da20a 6c416e50 be794ca4;x= 145808759246485357699436151405787061398457272130,y= 5caa767d c9789415 02464901 517741b9 b3b72442 2cde8f0e c9a9d20c f44c60af1e7922a8 2e74c2b1 f59c17be 3d82032e de897275 09a5a090 d448e4b3 eff337ef。
对明文“I LOVE CHINA.”生成签名消息302C02143DCCEEE146D6438B35103DDB4A0EABBBF8A5C9CE02146816E530B17AF1FDBC29018569B6A4D2 62BCC098。
关键步骤截图如下:②对消息做很小的改动,再次生成“I LOVE CHINA!”生成签名消息302C02146E8554AB3C098BC09A8D3720571B2D294236CC6F021*******AD3395C717065FCD993173082BE1CF B5EB。
关键步骤截图如下:签名一:签名二:五、实验小结1、本次实验虽然在代码验证阶段遇到很多问题,尝试了好几种语言,但是后来的实验过程中基本没有遇到什么问题。
2、通过这个实验我也明白了DSA签名算法怎么验证。
3、网上看了一些关于安全的信息:DSA只能与SHA-1一起使用,而RSA可以与任何摘要算法一起使用。
DSA签名不包括摘要标识符,所以如果允许多种摘要算法就会使DSA遭受前面RSA里面介绍的那种替换攻击。
DSA主要依赖于整数有限域离散对数难题。
素数P 必须足够大,且p-1至少包含一个大素数因子以抵抗Pohlig & Hellman算法的攻击。
M一般都应采用信息的HASH值(官方推荐为SHA算法)。
DSA的安全性主要依赖于p和g,若选取不当则签名容易伪造,应保证g 对于p-1的大素数因子不可约。
DSA算法在破解时关键的参数就是X 根据Y = G^X mod P 只要知道P,G,Y,Q 且能分解出X 就可以伪造R,S写出KeyGen了。
个人观点DSA 的安全性要次于ECC 与RSA不相上下。
但是有一点,就是DSA算法的验证过程R,S 是以明文形式出现的,这点很容易被利用。