eclipse实现ElGamal数字签名
作者:秃头选拔赛形象大使 发布时间:2023-11-26 07:52:47
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)解密/验证方面,解密算法采用 恢复明文,而签名验证算法采用公式 来验证签名是否吻合。
来源:https://blog.csdn.net/qq_45056216/article/details/106894190
猜你喜欢
- 一、打印直角三角形这个循环控制打印十行空格for (int x = 1; x <= 10; x++) {//因为要打印一个十行的直角三
- 我们都知道mybatis在进行参数判断的时候,直接可以用<if test=""></if> 就可
- 代码如下:try { // 创建一个线程 Thread thread = new Thread() {
- 1、错误的解决方案1.1、 先更新数据库,再删除缓存若数据库更新成功,删除缓存操作失败,则此后读到的都是缓存中过期的数据,造成不一致问题。1
- 为什么要自定义缓存注解?Spring Cache本身提供@Cacheable、@CacheEvict、@CachePut等缓存注解,为什么还
- 本篇实例内容是关于C#读取CAD文件的,直接看代码//在不使用任务插件的情况下读取DWG文件的缩略图,以便在没有安装AutoCAD的计算机上
- makeCertPic.javapackage pic;import java.awt.Color;import java.awt.Font
- 这是一个高级Java面试系列题中的第一部分。这一部分论述了可变参数,断言,垃圾回收,初始化器,令牌化,日期,日历等等Java核心问题。接下来
- IoC的概念介绍控制反转(IOC)模式(又称DI:Dependency Injection)就是Inversion of Control,控
- 目录栈溢出(虚拟机栈和本地方法栈)产生原因解决思路堆溢出产生原因解决思路方法区和运行时常量池溢出产生原因解决思路本机直接内存溢出产生原因解决
- java语言里包含了许多对设计模式的直接支持,如command模式,agent模式,observer模式等。虽然java提供的对
- 自从SEOTcs系统11月份24日更新了一下SEO得分算法以来,一直困扰我的一个问题出现了,java的数据job任务,在执行过程中会经常报以
- 走马灯是一种常见的效果,本文讲一下如何用 PageView 在 Flutter 里实现一个走马灯, 效果如下,当前页面的高度比其它页面高,切
- 开篇语Synchronized,Java 友好的提供了的一个关键字,它让开发者可以快速的实现同步。它就像一个星星,远远看去就是一个小小的点。
- 定义:动态给一个对象添加一些额外的职责,就象在墙上刷油漆.使用Decorator模式相比用生成子类方式达到功能的扩充显得更为灵活。设计初衷:
- 最近在做一个项目,遇到了项目打成 war 包的一个问题,项目创建时选择的时 jar 包方式,后因项目部署要求,需要打成 war 包部署,遇到
- 目录1.前言2.不同进制的特点3.进制之间的转换3.1 二进制转十进制:3.2 十进制转二进制:3.3 二进制转八进制:3.4 十六进制转二
- 封面图下个季度的目标是把前端监控相关的内容梳理出来,梳理出来之后可能会在公司内部做个分享~Flutter应用程序既括代码也包括一些其他的资产
- 本文实例讲解了iOS从背景图中取色的代码,分享给大家供大家参考,具体内容如下实现代码:void *bitmapData; //内存空间的指针
- Idea2020.2创建JavaWeb的方式略有改动,以下做个记录,大家可以参考下,对以后的工作有所帮助!1.创建项目不再是Java Ent