歡迎您光臨本站 註冊首頁

eclipse實現ElGamal數字簽名

←手機掃碼閱讀     kyec555 @ 2020-06-24 , reply:0

ElGamal數字簽名,供大家參考,具體內容如下

一、實驗目的

學習ElGamal演演算法在數字簽名方面的使用,掌握教科書版本的ElGamal數字簽名演演算法的編寫,掌握ElGamal加密演演算法和ElGamal數字簽名演演算法的異同。

二、實驗要求

1.熟悉ElGamal數字簽名演演算法。
 2.掌握如何使用Java BigInteger類,簡單實現教科書式的ElGamal公私鑰簽名演演算法。
 3.瞭解ElGamal加密演演算法和ElGamal數字簽名演演算法的異同。

三、開發環境

JDK 1.7,Java開發環境(本實驗採用Windows+eclipse作為實驗環境),要求參與實驗的同學按照對稱加密提供的方法,提前安裝好JDK。

四、實驗內容

【1-1】ElGamal簽名演演算法的實現

1.實現公私鑰生成演演算法:根據教材,ElGamal公私鑰生成演演算法首選需要選取一個大素數 ,然後選取 作為其生成元。接著隨機選取私鑰 ,計算 作為其公鑰。因此,可寫程式碼如下:

  public void initKeys() {   System.out.println("choose a prime p with securitylevel "    + securitylevel + " , please wait ...");   p = new BigInteger(securitylevel, 100, new Random());   System.out.println("p : " + p);   g = __randomInZp();   System.out.println("g : " + g);   x = __randomInZp();   System.out.println("x : " + x);   y = g.modPow(x, p);   System.out.println("y : " + y);     }

 

其中,__randomInZp定義如下函式,實現從 中隨機選取一個大整數:

  public BigInteger __randomInZp() {   BigInteger r = null;   do {   System.out.print(".");   r = new BigInteger(securitylevel, new SecureRandom());   }while(r.compareTo(p) >= 0);   System.out.println(".");   return r;  }

 

2.實現簽名演演算法:

ElGamal簽名演演算法需要隨機選取 ,同時計算
 此時, 即為簽名。因此,可根據公式,寫程式碼如下:

  public BigInteger[] signature(byte m[]) {   BigInteger sig[] = new BigInteger[2];   BigInteger k = __randomPrimeInZp();   sig[0] = g.modPow(k, p);   sig[1] = __hashInZp(m).subtract(x.multiply(sig[0]))   .mod(p.subtract(BigInteger.ONE))   .multiply(k.modInverse(p.subtract(BigInteger.ONE)))   .mod(p.subtract(BigInteger.ONE));   System.out.println("[r,s] = [" + sig[0] + ", " + sig[1] + "]");   return sig;  }

 

此處的__randomPrimeInZp意為從 中隨機選取一個大素數,實現如下:

  public BigInteger __randomPrimeInZp() {   BigInteger r = null;   do {   System.out.print(".");   r = new BigInteger(securitylevel, 100, new SecureRandom());   }while(r.compareTo(p) >= 0);   System.out.println(".");   return r;  }

 

另有一雜湊函式,實現如下:

  public BigInteger __hashInZp(byte m[]) {   MessageDigest md;   try {   md = MessageDigest.getInstance("SHA-256");   md.update(m);    byte b[] = new byte[33];    System.arraycopy(md.digest(), 0, b, 1, 32);    return new BigInteger(b);   } catch (NoSuchAlgorithmException e) {   System.out.println("this cannot happen.");   }   return null;  }

 

3.實現驗證演演算法:ElGamal簽名驗證演演算法即判定公式 是否成立。因此,可考慮寫程式碼如下:

  public boolean verify(byte m[], BigInteger sig[]) {   BigInteger l = y.modPow(sig[0], p)   .multiply(sig[0].modPow(sig[1], p)).mod(p);   BigInteger r = g.modPow(__hashInZp(m), p);   return l.compareTo(r) == 0;  }

 

4.實現main方法,在main方法中呼叫演演算法進行測試:

  public static void main(String args[]) {   ElGamalSignatureInstance instance = new ElGamalSignatureInstance();   instance.initKeys();   byte m[] = "my name is ElGamal, my student number is 201300012345.".getBytes();   BigInteger sig[] = instance.signature(m);   System.out.println("Real signature verify result : " + instance.verify(m, sig));   sig[0] = sig[0].add(BigInteger.ONE);   System.out.println("Faked signature verify result : " + instance.verify(m, sig));  }

 

【1-2】完整參考程式碼

  import java.math.BigInteger;  import java.security.MessageDigest;  import java.security.NoSuchAlgorithmException;  import java.security.SecureRandom;  import java.util.Random;      public class ElGamalSignatureInstance {   int securitylevel = 1024;   BigInteger p, g, x, y;      public BigInteger __randomInZp() {   BigInteger r = null;   do {   System.out.print(".");   r = new BigInteger(securitylevel, new SecureRandom());   }while(r.compareTo(p) >= 0);   System.out.println(".");   return r;   }      public BigInteger __randomPrimeInZp() {   BigInteger r = null;   do {   System.out.print(".");   r = new BigInteger(securitylevel, 100, new SecureRandom());   }while(r.compareTo(p) >= 0);   System.out.println(".");   return r;   }      public BigInteger __hashInZp(byte m[]) {   MessageDigest md;   try {   md = MessageDigest.getInstance("SHA-256");   md.update(m);    byte b[] = new byte[33];    System.arraycopy(md.digest(), 0, b, 1, 32);    return new BigInteger(b);   } catch (NoSuchAlgorithmException e) {   System.out.println("this cannot happen.");   }    return null;   }      public void initKeys() {   System.out.println("choose a prime p with securitylevel " + securitylevel + " , please wait ...");   p = new BigInteger(securitylevel, 100, new Random());   System.out.println("p : " + p);   g = __randomInZp();   System.out.println("g : " + g);   x = __randomInZp();   System.out.println("x : " + x);   y = g.modPow(x, p);   System.out.println("y : " + y);      }      public BigInteger[] signature(byte m[]) {   BigInteger sig[] = new BigInteger[2];   BigInteger k = __randomPrimeInZp();   sig[0] = g.modPow(k, p);   sig[1] = __hashInZp(m).subtract(x.multiply(sig[0])).mod(p.subtract(BigInteger.ONE))   .multiply(k.modInverse(p.subtract(BigInteger.ONE))).mod(p.subtract(BigInteger.ONE));   System.out.println("[r,s] = [" + sig[0] + ", " + sig[1] + "]");   return sig;   }      public boolean verify(byte m[], BigInteger sig[]) {   BigInteger l = y.modPow(sig[0], p).multiply(sig[0].modPow(sig[1], p)).mod(p);   BigInteger r = g.modPow(__hashInZp(m), p);   return l.compareTo(r) == 0;   }      public static void main(String args[]) {   ElGamalSignatureInstance instance = new ElGamalSignatureInstance();   instance.initKeys();   byte m[] = "my name is ElGamal, my student number is 201300012345.".getBytes();   BigInteger sig[] = instance.signature(m);   System.out.println("Real signature verify result : " + instance.verify(m, sig));   sig[0] = sig[0].add(BigInteger.ONE);   System.out.println("Faked signature verify result : " + instance.verify(m, sig));   }  }

 

由於產生隨機大素數的方法(即__randomPrimeInZp)的執行速度受到 值和電腦CPU速度的影響,在某些同學的電腦上可能出現選取引數緩慢的問題。此時可將securitylevel的值調低(預設1024,可調低到512),即可提高速度。但注意調低securitylevel將會導致安全強度下降。
 

【1-5】擴充套件內容:ElGamal加密演演算法和ElGamal簽名演演算法有何異同?
 答:
 

(1)在產生公私鑰方面,二者幾乎完全一致。
 (2)加密/簽名步驟,都需要先選取一個隨機數 並計算 作為其密文的第一分量(這也是ElGamal的概率輸出的原因所在)。不同點在於,加密演演算法後續採用 的方式產生密文第二分量,而簽名演演算法採用了 作為其第二分量。
 (3)解密/驗證方面,解密演演算法採用 恢復明文,而簽名驗證演演算法採用公式 來驗證簽名是否吻合。


[kyec555 ] eclipse實現ElGamal數字簽名已經有295次圍觀

http://coctec.com/docs/developer/show-post-239557.html