失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > elgamal java_eclipse实现ElGamal数字签名

elgamal java_eclipse实现ElGamal数字签名

时间:2020-02-07 12:00:53

相关推荐

elgamal java_eclipse实现ElGamal数字签名

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(pareTo(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(pareTo(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 pareTo(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 00012345.".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(pareTo(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(pareTo(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 pareTo(r) == 0;

}

public static void main(String args[]) {

ElGamalSignatureInstance instance = new ElGamalSignatureInstance();

instance.initKeys();

byte m[] = "my name is ElGamal, my student number is 00012345.".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)解密/验证方面,解密算法采用 恢复明文,而签名验证算法采用公式 来验证签名是否吻合。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

如果觉得《elgamal java_eclipse实现ElGamal数字签名》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。