DSA數字簽名,供大家參考,具體內容如下
一、實驗目的
在掌握了ElGamal和Schorr數字簽名演演算法的基礎上,進一步地學習和掌握DSA簽名演演算法。深入地理解該演演算法是如何降低了簽名資訊的長度(當其中一個重要引數 選為512bit的素數時,ElGamal簽名的長度為1024bit,而DSA中透過160bit的素數 可以將簽名的長度降低為320bit),從而減少了儲存空間和傳輸頻寬。
二、實驗要求
4.學習DSA數字簽名演演算法。
5.掌握如何使用Java BigInteger類,簡單實現最基礎的DSA公私鑰簽名演演算法。
6.深入地理解DSA簽名演演算法與RSA演演算法的區別。
三、開發環境
JDK 1.7,Java開發環境(本實驗採用Windows+eclipse作為實驗環境),要求參與實驗的同學按照對稱加密提供的方法,提前安裝好JDK。
四、實驗原理
掌握了ElGamal和Schorr數字簽名演演算法的基礎上,進一步地學習和掌握DSA簽名演演算法。深入地理解該演演算法是如何降低了簽名資訊的長度(當其中一個重要引數 選為512bit的素數時,ElGamal簽名的長度為1024bit,而DSA中透過160bit的素數 可以將簽名的長度降低為320bit),從而減少了儲存空間和傳輸頻寬
程式碼段:
import java.math.BigInteger; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Random; public class DSASign { public BigInteger p,q,g; public BigInteger x,y; public BigInteger _randomInZq(){ BigInteger r= null; do { System.out.print("."); r = new BigInteger(160, new SecureRandom()); }while(r.compareTo(q) >=0); System.out.print("."); return r; } public BigInteger _hashInZq(byte m[]){ MessageDigest md; try { md = MessageDigest.getInstance("SHA-1"); md.update(m); byte b[] = new byte[17]; System.arraycopy(md.digest(), 0, b, 1, 16); return new BigInteger(b); }catch (NoSuchAlgorithmException e){ System.out.print("This cannot happen!"); } return null; } public void initKeys(){ q = new BigInteger(160, 100, new SecureRandom()); do { BigInteger t = new BigInteger(512, new SecureRandom()); p = t.multiply(q).add(BigInteger.ONE); System.out.println("~"); }while(!p.isProbablePrime(100)); BigInteger h = _randomInZq(); g = h.modPow(p.subtract(BigInteger.ONE).divide(q), p); x = _randomInZq(); y = g.modPow(x, p); System.out.println("p : " + p); System.out.println("q : " + q); System.out.println("g : " + g); System.out.println("x : " + x); System.out.println("y : " + y); } public BigInteger[] signature(byte m[]){ BigInteger k = _randomInZq(); BigInteger sig[] = new BigInteger[2]; sig[0] = g.modPow(k, p).mod(q); sig[1] = _hashInZq(m).add(x.multiply(sig[0])).mod(q) .multiply(k.modInverse(q)).mod(q); return sig; } public boolean verify(byte m[], BigInteger sig[]){ BigInteger w = sig[1].modInverse(q); BigInteger u1 = _hashInZq(m).multiply(w).mod(q); BigInteger u2 = sig[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 = " + sig[0]); return v.compareTo(sig[0]) == 0; } public static void main(String args[]){ DSASign dsa = new DSASign(); dsa.initKeys(); String message = "My name is xxx, my student number is xxxx."; System.out.println(message); BigInteger sig[] = dsa.signature(message.getBytes()); System.out.println("DSASignture verifies result:" + dsa.verify(message.getBytes(),sig) ); } }
[madbeef ] eclipse實現DSA數字簽名已經有255次圍觀