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