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
猜你喜欢
- 一般来说,修改框架的源代码是极其有风险的,除非万不得已,否则不要去修改。但是今天却小心翼翼的重构了Mybatis官方提供的与Spring集成
- ArrayList底层实现是数组,访问元素效率高 (查询快,插入、修改、删除元素慢)与LinkedList相比,它效率高,但线程不安全。Ar
- 第一个System.Runtime.InteropServices.Marshal.ReleaseComObject(sheets);&nb
- 本文实例讲述了Java方法的参数传递机制。分享给大家供大家参考,具体如下:参数传递机制对于程序设计语言来说,一般方法(函数)的参数传递有两种
- 在C#中,得益于强大的GC机制,使得我们开发程序变得非常简单,很多时候我们只需要管使用,而并不需要关心什么时候释放资源。但是,GC有的时并不
- 本文实例讲述了Java编程使用卡片布局管理器。分享给大家供大家参考,具体如下:运行效果:完整示例代码:package com.han;imp
- 无论是用Eclipse还是用Android Studio做android开发,都会接触到jar包,全称应该是:Java Archive,即j
- 本文实例讲述了Android开发之绘制平面上的多边形功能。分享给大家供大家参考,具体如下:计算机里的3D图形其实是由很多个平面组合而成的。所
- 一、ID生成策略1、使用@TableId注解@TableId注解:主键注解使用位置:实体类主键字段。@Data@ToString@Table
- 在项目中如果有些参数经常需要修改,或者后期可能需要修改,那我们最好把这些参数放到properties文件中,源代码中读取properties
- 1、直接使用getWindow().getDecorView().getRootView()直接使用getWindow().getDecor
- 1、idea构建web项目idea构建web项目的超级详细教程,一步一步来,完全没问题!1、新建一个空项目2、新建java模块,名为webD
- 这篇文章主要介绍了Java如何基于ProcessBuilder类调用外部程序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的
- Android的设置界面实现比较简单,有时甚至只需要使用一个简单的xml文件即可.声明简单,但是如何从PreferenceScreen或者P
- 微服务治理Spring Cloud 工具套件为微服务治理提供了全面的技术支持。这些治理工具主要包括服务的注册与发现、负载均衡管理、动态路由、
- 先说能用的究极解决方案,大家着急的直接复制走,以后想了解再过来看没有header,且所有Item的高度一致private fun getSc
- 1、图的定义我们知道,前面讨论的数据结构都有一个框架,而这个框架是由相应的算法实现的,比如二叉树搜索树,左子树上所有结点的值均小于它的根结点
- 记得上学的时候学习英语,每个英语老师说到英语翻译的时候都会说英语翻译要做到“信、达、雅”。如今做了一名程序员竟然体会我还是想用这三种境界来要
- 一、简介上篇介绍了一个自己做的管理系统,最近空闲的时间自己在继续做,把之前登录时候自定义的 * 过滤器换成了基于SpringSecurity
- 关于静态类型检查和动态类型检查的解释:静态类型检查:基于程序的源代码来验证类型安全的过程;动态类型检查:在程序运行期间验证类型安全的过程;J