java dsa算法_DSA算法
DSA(Digital Signature Algorithm)是Schnorr和ElGamal簽名算法的變種,被美國(guó)NIST作為DSS(DigitalSignature Standard)。
DSA加密算法主要依賴于整數(shù)有限域離散對(duì)數(shù)難題,素?cái)?shù)P必須足夠大,且p-1至少包含一個(gè)大素?cái)?shù)因子以抵抗Pohlig &Hellman算法的攻擊。M一般都應(yīng)采用信息的HASH值。DSA加密算法的安全性主要依賴于p和g,若選取不當(dāng)則簽名容易偽造,應(yīng)保證g對(duì)于p-1的大素?cái)?shù)因子不可約。其安全性與RSA相比差不多。
DSA 一般用于數(shù)字簽名和認(rèn)證。在DSA數(shù)字簽名和認(rèn)證中,發(fā)送者使用自己的私鑰對(duì)文件或消息進(jìn)行簽名,接受者收到消息后使用發(fā)送者的公鑰來(lái)驗(yàn)證簽名的真實(shí)性。DSA只是一種算法,和RSA不同之處在于它不能用作加密和解密,也不能進(jìn)行密鑰交換,只用于簽名,它比RSA要快很多.
1. DSA簽名及驗(yàn)證
DSA算法中應(yīng)用了下述參數(shù):
p:L bits長(zhǎng)的素?cái)?shù)。L是64的倍數(shù),范圍是512到1024;
q:p – 1的160bits的素因子;
g:g = h^((p-1)/q) mod p,h滿足h < p – 1, h^((p-1)/q) mod p > 1;
x:x < q,x為私鑰 ;
y:y = g^x mod p ,( p, q, g, y )為公鑰;
H( x ):One-Way Hash函數(shù)。DSS中選用SHA( Secure Hash Algorithm )。
p, q, g可由一組用戶共享,但在實(shí)際應(yīng)用中,使用公共模數(shù)可能會(huì)帶來(lái)一定的威脅。
簽名及驗(yàn)證協(xié)議:1.P產(chǎn)生隨機(jī)數(shù)k,k < q;
2.P計(jì)算 r = ( g^k mod p ) mod q
s = ( k^(-1) (H(m) xr)) mod q
簽名結(jié)果是( m, r, s )。
3.驗(yàn)證時(shí)計(jì)算 w = s^(-1)mod q
u1 = ( H( m ) w ) mod q
u2 = ( r w ) mod q
v = (( g^u1 * y^u2 ) mod p ) mod q
若v = r,則認(rèn)為簽名有效。
舉例:B 發(fā)消息給A,使用DSA算法進(jìn)行簽名
1.生成素?cái)?shù)p=59、素?cái)?shù)q=29、h=11、私鑰x=7,臨時(shí)密鑰k=10,消息摘要H(M)=26
2.生成g:
g=h^(p-1)/qmod p g=11^2 mod 59 g=3
3.計(jì)算公鑰y
y=g^xmod p y=3^7 mod 59 y=2187 mod 59 y=4
4.進(jìn)行簽名計(jì)算
r = (g^k mod p) mod q r=(59049 mod 59) mod 29 r=20
s = [k^-1 (H(M) + xr) ] mod q s=3·(26+140)mod 29 s=5
5.A收到消息后進(jìn)行簽名驗(yàn)證
w=(s’)^-1mod q w=6 mod 29 =6
u1=[H(M’)w] mod q u1=156 mod 29 = 11
u2=(r’)wmod q u2=120 mod 29=4
v=[(g^u1 · y^u2) mod p] mod q v= (45349632 mod 59) mod 29 =20
v=r=20
6.驗(yàn)證成功;
2.DSA使用過(guò)程
過(guò)程:構(gòu)建密鑰對(duì):
發(fā)送方: 1.構(gòu)建密鑰對(duì)
2.公布密鑰
發(fā)送數(shù)據(jù)?:
發(fā)送方: 1.使用私鑰對(duì)數(shù)據(jù)簽名
2.發(fā)送簽名,數(shù)據(jù)
3.使用公鑰,簽名驗(yàn)證數(shù)據(jù)
3. Java實(shí)現(xiàn)DSA生成公私鑰并加解密
3.1代碼如下package?com.tencent.blue.utils;import?java.io.FileInputStream;import?java.io.FileOutputStream;import?java.io.ObjectInputStream;import?java.io.ObjectOutputStream;import?java.security.*;/**
*?Created?by?cuiran?on?19/1/11.
*?生成一對(duì)文件?publicKey.key?和?privateKey.key?,
*?公鑰要用戶發(fā)送?(?文件?,?網(wǎng)絡(luò)等方法?)?給其它用戶?,?私鑰保存在本地
*?1.生成秘鑰對(duì)
*?2.使用私鑰進(jìn)行簽名
*?3.使用公鑰校驗(yàn)簽名
*?意義上的加密解密?非內(nèi)容型的加密解密
*/public?class?DSA?{????public?static?void?main(String[]?args)?{????????//初始化秘鑰對(duì)寫入到文件?生成的是X.509編碼格式的?生成的私鑰是PKCS#8編碼格式
getKeyPairs();????????//明文簽名
SignatureData("我是cayden,銀行賬戶為622XXXX");????????//校驗(yàn)簽名文件
checkSignature();
}????/**
*?生成秘鑰對(duì)寫入到文件
*?@return
*/
public?static?boolean?getKeyPairs()?{????????try?{????????????//初始化秘鑰管理器
KeyPairGenerator?keyPairGenerator?=?KeyPairGenerator.getInstance("DSA");
keyPairGenerator.initialize(512);
KeyPair?keyPair?=?keyPairGenerator.genKeyPair();????????????//獲取秘鑰對(duì)
PublicKey?publicKey?=?keyPair.getPublic();
PrivateKey?privateKey?=?keyPair.getPrivate();????????????//直接寫入公鑰
ObjectOutputStream?out_pub?=?new?ObjectOutputStream(new?FileOutputStream("publicKey.key"));
out_pub.writeObject(publicKey);
out_pub.close();
System.out.println("生成的公鑰內(nèi)容為_____:\n?"+publicKey);????????????//直接寫入私鑰
ObjectOutputStream?out_pri?=?new?ObjectOutputStream(new?FileOutputStream("privateKey.key"));
out_pri.writeObject(privateKey);
out_pri.close();
System.out.println("生成的私鑰內(nèi)容為_____:\n?"+privateKey);
System.out.println("\n生成密鑰對(duì)成功...");????????????return?true;
}?catch?(java.lang.Exception?e)?{
e.printStackTrace();????????????return?false;
}
}????/**
*?使用私鑰進(jìn)行簽名
*?@return
*/
public?static?boolean?SignatureData(String??info){????????try?{????????????//1.讀取生成的私鑰對(duì)明文進(jìn)行簽名
ObjectInputStream?in_pri?=?new?ObjectInputStream(new?java.io.FileInputStream("privateKey.key"));
PrivateKey?privateKey?=?(PrivateKey)?in_pri.readObject();
in_pri.close();????????????//初始化簽名?對(duì)明文開始簽名
Signature?signature?=?Signature.getInstance("DSA");
signature.initSign(privateKey);
signature.update(info.getBytes());????????????//?對(duì)信息的數(shù)字簽名
byte[]?signedbytes?=?signature.sign();
System.out.println("簽名為_____:"+signedbytes);????????????//把簽名的密文存到文件中
ObjectOutputStream?out_signature?=new?ObjectOutputStream(new?FileOutputStream("signature.data"));????????????//把明文和簽名一起寫入?也可以分別寫入
out_signature.writeObject(info);
out_signature.writeObject(signedbytes);
out_signature.close();
System.out.println("秘鑰簽名完成.......");
}?catch?(Exception?e)?{
e.printStackTrace();
System.out.println("私鑰簽名失敗....");
}????????return?false;
}????/**
*?用公鑰進(jìn)行校驗(yàn)
*?@return
*/
public?static?boolean?checkSignature(){????????try?{????????????//讀取公鑰
ObjectInputStream?in_pub=new?ObjectInputStream(new?FileInputStream("publicKey.key"));
PublicKey?publicKey?=?(PublicKey)?in_pub.readObject();????????????//讀取簽名文件
ObjectInputStream?in_signature=new?ObjectInputStream(new?FileInputStream("signature.data"));????????????//讀取簽名信息
String?info?=?(String)?in_signature.readObject();????????????//用公鑰進(jìn)行校驗(yàn)
byte[]?signedbytes?=?(byte[])?in_signature.readObject();
Signature?signature?=?Signature.getInstance("DSA");
signature.initVerify(publicKey);
signature.update(info.getBytes());????????????//簽名信息校驗(yàn)
if?(signature.verify(signedbytes))?{
System.out.println("簽名的內(nèi)容為____:"?+?info);
System.out.println("簽名文件校驗(yàn)正常....");????????????????return?true;
}?else{
System.out.println("簽名校驗(yàn)失敗");????????????????return?false;
}
}?catch?(Exception?e)?{
e.printStackTrace();????????????return?false;
}
}
}
3.2 運(yùn)行結(jié)果如下
運(yùn)行結(jié)果
作者:一杯茶一本書
鏈接:https://www.jianshu.com/p/8a40e4191bb8
總結(jié)
以上是生活随笔為你收集整理的java dsa算法_DSA算法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: go.php跳转外部浏览器,Go调用浏览
- 下一篇: 【单片机】C51中的定时/计数器介绍