eclipse實(shí)現(xiàn)ElGamal數(shù)字簽名
ElGamal數(shù)字簽名,供大家參考,具體內(nèi)容如下
一、實(shí)驗(yàn)?zāi)康?/strong>
學(xué)習(xí)ElGamal算法在數(shù)字簽名方面的使用,掌握教科書(shū)版本的ElGamal數(shù)字簽名算法的編寫(xiě),掌握ElGamal加密算法和ElGamal數(shù)字簽名算法的異同。
二、實(shí)驗(yàn)要求
1.熟悉ElGamal數(shù)字簽名算法。
2.掌握如何使用Java BigInteger類,簡(jiǎn)單實(shí)現(xiàn)教科書(shū)式的ElGamal公私鑰簽名算法。
3.了解ElGamal加密算法和ElGamal數(shù)字簽名算法的異同。
三、開(kāi)發(fā)環(huán)境
JDK 1.7,Java開(kāi)發(fā)環(huán)境(本實(shí)驗(yàn)采用Windows+eclipse作為實(shí)驗(yàn)環(huán)境),要求參與實(shí)驗(yàn)的同學(xué)按照對(duì)稱加密提供的方法,提前安裝好JDK。
四、實(shí)驗(yàn)內(nèi)容
【1-1】ElGamal簽名算法的實(shí)現(xiàn)
1.實(shí)現(xiàn)公私鑰生成算法:根據(jù)教材,ElGamal公私鑰生成算法首選需要選取一個(gè)大素?cái)?shù) ,然后選取 作為其生成元。接著隨機(jī)選取私鑰 ,計(jì)算 作為其公鑰。因此,可寫(xiě)代碼如下:
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定義如下函數(shù),實(shí)現(xiàn)從 中隨機(jī)選取一個(gè)大整數(shù):
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.實(shí)現(xiàn)簽名算法:
ElGamal簽名算法需要隨機(jī)選取 ,同時(shí)計(jì)算
此時(shí), 即為簽名。因此,可根據(jù)公式,寫(xiě)代碼如下:
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意為從 中隨機(jī)選取一個(gè)大素?cái)?shù),實(shí)現(xiàn)如下:
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; }
另有一哈希函數(shù),實(shí)現(xiàn)如下:
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.實(shí)現(xiàn)驗(yàn)證算法:ElGamal簽名驗(yàn)證算法即判定公式 是否成立。因此,可考慮寫(xiě)代碼如下:
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.實(shí)現(xiàn)main方法,在main方法中調(diào)用算法進(jìn)行測(cè)試:
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)); } }
注
由于產(chǎn)生隨機(jī)大素?cái)?shù)的方法(即__randomPrimeInZp)的運(yùn)行速度受到 值和電腦CPU速度的影響,在某些同學(xué)的電腦上可能出現(xiàn)選取參數(shù)緩慢的問(wèn)題。此時(shí)可將securitylevel的值調(diào)低(缺省1024,可調(diào)低到512),即可提高速度。但注意調(diào)低securitylevel將會(huì)導(dǎo)致安全強(qiáng)度下降。
【1-5】擴(kuò)展內(nèi)容:ElGamal加密算法和ElGamal簽名算法有何異同?
答:
(1)在產(chǎn)生公私鑰方面,二者幾乎完全一致。
(2)加密/簽名步驟,都需要先選取一個(gè)隨機(jī)數(shù) 并計(jì)算 作為其密文的第一分量(這也是ElGamal的概率輸出的原因所在)。不同點(diǎn)在于,加密算法后續(xù)采用 的方式產(chǎn)生密文第二分量,而簽名算法采用了 作為其第二分量。
(3)解密/驗(yàn)證方面,解密算法采用 恢復(fù)明文,而簽名驗(yàn)證算法采用公式 來(lái)驗(yàn)證簽名是否吻合。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot的jar包如何啟動(dòng)的實(shí)現(xiàn)
本文主要介紹了SpringBoot的jar包如何啟動(dòng)的實(shí)現(xiàn),文中根據(jù)實(shí)例編碼詳細(xì)介紹的十分詳盡,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03Java求字符串中出現(xiàn)次數(shù)最多的字符串以及出現(xiàn)次數(shù)
這篇文章主要為大家詳細(xì)介紹了Java統(tǒng)計(jì)字符串中出現(xiàn)次數(shù)最多的字符串以及出現(xiàn)次數(shù),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04spring boot啟動(dòng)加載數(shù)據(jù)原理分析
實(shí)際應(yīng)用中,我們會(huì)有在項(xiàng)目服務(wù)啟動(dòng)的時(shí)候就去加載一些數(shù)據(jù)或做一些事情這樣的需求。這時(shí)spring Boot 為我們提供了一個(gè)方法,通過(guò)實(shí)現(xiàn)接口 CommandLineRunner 來(lái)實(shí)現(xiàn)。下面給大家詳細(xì)介紹下,需要的的朋友參考下吧2017-04-04java實(shí)現(xiàn)自定義日期選擇器的方法實(shí)例
日期選擇器是我們?nèi)粘i_(kāi)發(fā)中經(jīng)常需要用到的一個(gè)功能,下面這篇文章主要給大家介紹了關(guān)于利用java實(shí)現(xiàn)自定義日期選擇器的相關(guān)資料,文中給出了詳細(xì)的示例代碼,需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-10-10jfinal添加jcaptcha驗(yàn)證碼實(shí)現(xiàn)方法
這篇文章主要介紹了jfinal的jcaptcha驗(yàn)證碼實(shí)現(xiàn)方法,大家參考使用吧2014-01-01Java Management Extensions管理擴(kuò)展原理解析
這篇文章主要介紹了Java Management Extensions管理擴(kuò)展原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04