eclipse实现ElGamal数字签名

 更新时间:2020年06月23日 14:03:35   作者:秃头选拔赛形象大使  
这篇文章主要为大家详细介绍了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(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)解密/验证方面,解密算法采用 恢复明文,而签名验证算法采用公式 来验证签名是否吻合。

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

相关文章

  • Java多线程死锁问题详解(wait和notify)

    Java多线程死锁问题详解(wait和notify)

    线程之间形成相互等待资源的环时,就会形成顺序死锁,下面这篇文章主要给大家介绍了关于Java多线程死锁问题(wait和notify)的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2023-01-01
  • SpringBoot整合Solr实现文档检索

    SpringBoot整合Solr实现文档检索

    Solr高度可靠、可扩展和容错,提供分布式索引、复制和负载平衡查询、自动故障转移和恢复、集中配置等,Solr 为世界上许多最大的 Internet 站点的搜索和导航功能提供支持,本文将给大家介绍SpringBoot整合Solr实现文档检索,需要的朋友可以参考下
    2023-08-08
  • 如何把第三方服务注册到spring项目容器中

    如何把第三方服务注册到spring项目容器中

    这篇文章主要为大家介绍了如何把第三方服务注册到spring项目容器中,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Java数组实现动态初始化的实例详解

    Java数组实现动态初始化的实例详解

    在本篇文章里小编给大家整理的是一篇关于Java数组实现动态初始化的实例详解内容,有兴趣的朋友们可以学习下。
    2021-10-10
  • spring cloud-zuul的Filter使用详解

    spring cloud-zuul的Filter使用详解

    这篇文章主要介绍了spring cloud-zuul的Filter使用详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • SpringBoot实现MQTT消息发送和接收方式

    SpringBoot实现MQTT消息发送和接收方式

    这篇文章主要介绍了SpringBoot实现MQTT消息发送和接收方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • spring boot 使用Mybatis-plus查询方法解析

    spring boot 使用Mybatis-plus查询方法解析

    这篇文章主要介绍了spring boot 使用Mybatis-plus查询方法解析,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09
  • springBoot基于webSocket实现扫码登录

    springBoot基于webSocket实现扫码登录

    最近做了个新项目,涉及到扫码登录。之前项目使用的是 ajax轮询的方式。感觉太low了。所以这次用webSocket的方式进行实现,感兴趣的可以了解一下
    2021-06-06
  • Spring 注入集合实现过程示例详解

    Spring 注入集合实现过程示例详解

    这篇文章主要为大家介绍了Spring 注入集合实现过程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • 128进制加密数据示例分享

    128进制加密数据示例分享

    这篇文章主要介绍了128进制加密数据示例,这里使用JAVA实现,需要的朋友可以参考下
    2014-03-03

最新评论