DSA数字签名理论分析及代码实现
程序员文章站
2024-03-19 14:10:52
...
DSA数字签名理论分析
1、准备
素数p:约512+比特(512~1024位的素数);
素数q:约160比特,要求是p-1的因子,并与 p-1 互素的因子,q 能整除 p-1;
参数g:g=h((p-1)/q) mod p;其中 h < p-1 且 h((p-1)/q) mod p >1;
2、**
私钥x:x < q ;
公钥y:y=???????? mod p ;
3、签名
k-随机数
r=(????????mod p) mod q;
s= k-1 (H(M)+xr) mod q;
(r,s)即是签名
4、验签
u1=H(M’) ×s’-1 mod q;
u2=r’×s’-1 mod q;
v=gu1×yu2 mod p mod q;
若 v = r ;验签成功
Java代码实现DSA签名与验签
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
public class DSASignAndVerify {
/**
* 第一步 准备
*/
//系统参数 p,q,y 公开,私钥 x ,公钥 y
public BigInteger p,q,g,x,y;
//生成随机数 x ,要求 x < q
public BigInteger getX(){
BigInteger x= null;
do {
x = new BigInteger(160, new SecureRandom());
}while(x.compareTo(q) >=0);
return x;
}
//生成随机数 h ,要求 h < p - 1, h^((p-1)/q) mod p > 1
public BigInteger getH(){
BigInteger h= null;
do {
h = new BigInteger(160, new SecureRandom());
}while((h.compareTo(p.subtract(BigInteger.ONE))) >=0||(h.modPow(p.subtract(BigInteger.ONE).divide(q), p)).compareTo(BigInteger.ONE) <=0);
return h;
}
//对消息message进行哈希
public BigInteger getHashM(byte message[]){
MessageDigest messageDigest;
try {
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(message);
byte a[] = messageDigest.digest(message);
return new BigInteger(a);
}catch (NoSuchAlgorithmException e){
e.printStackTrace();
}
return null;
}
/**
* 第二步 初始化各参数,包括私钥 x 和公钥 y
*/
public void initParamsAndKeys(){
q = new BigInteger(160, 100, new SecureRandom());// q 为160bits素因子
do {
BigInteger t = new BigInteger(512, new SecureRandom());
p = t.multiply(q).add(BigInteger.ONE);// p : L bits长的素数.L是64倍数,范围[512, 1024]
}while(!p.isProbablePrime(100));
g = getH().modPow(p.subtract(BigInteger.ONE).divide(q), p);
x = getX();
y = g.modPow(x, p);
}
/**
* 第三步 签名和验签
* @param message 输入消息
* @return
*/
//签名
public BigInteger[] signature(byte message[]){
BigInteger k = new BigInteger(160, new SecureRandom());
BigInteger signature[] = new BigInteger[2];
signature[0] = g.modPow(k, p).mod(q);
signature[1] = getHashM(message).add(x.multiply(signature[0])).mod(q).multiply(k.modInverse(q)).mod(q);
return signature;
}
//验签
public boolean verify(byte message[], BigInteger signature[]){
BigInteger w = signature[1].modInverse(q);
BigInteger u1 = getHashM(message).multiply(w).mod(q);
BigInteger u2 = signature[0].multiply(w).mod(q);
BigInteger v = g.modPow(u1, p).multiply(y.modPow(u2, p)).mod(p).mod(q);
System.out.println("v = " + v);
System.out.println("r = " + signature[0]);
if(v.compareTo(signature[0]) == 0)
return true;
return false;
}
/**
* 主类测试
* @param args
*/
public static void main(String args[]){
DSASignAndVerify dsaSignAndVerify = new DSASignAndVerify();
dsaSignAndVerify.initParamsAndKeys();
String message = "区块链技术与应用";
System.out.println(message);
BigInteger signature[] = dsaSignAndVerify.signature(message.getBytes());
System.out.println(dsaSignAndVerify.verify(message.getBytes(),signature));
}
}
上一篇: 原代码审计笔记-质量缺陷