密码学实验-实验6 DSA数字签名算法
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
实验报告
一、实验目的
理解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
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 q
s=(H(M)+xr)k−1mod q
则M的签名为(r,s),其中H为Hash函数SHA。
3.验证算法
接收方收到消息M′和签名(r′,s′)后,计算
e1=H(M′)s′−1mod q
e2=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());