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)解密/验证方面,解密算法采用 恢复明文,而签名验证算法采用公式 来验证签名是否吻合。

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

(0)

相关推荐

  • Java数字签名算法DSA实例详解

    本文实例讲述了Java数字签名算法DSA.分享给大家供大家参考,具体如下: 一.介绍 DSS:Digital Signature Standard 数字签名标准 DSA:Digital Signature Algorithm 数字签名算法 DSA仅包含数字签名 二.参数说明 三.代码实现 package com.imooc.security.dsa; import java.security.KeyFactory; import java.security.KeyPair; import jav

  • Java加密解密和数字签名完整代码示例

    常见的加密算法 基本的单向加密算法: BASE64严格地说,属于编码格式,而非加密算法 MD5(MessageDigestalgorithm5,信息摘要算法) SHA(SecureHashAlgorithm,安全散列算法) HMAC(HashMessageAuthenticationCode,散列消息鉴别码) 复杂的对称加密(DES.PBE).非对称加密算法: DES(DataEncryptionStandard,数据加密算法) PBE(Password-basedencryption,基于密码

  • Eclipse下配置Ant脚本并自动打包带签名的Android apk

    eclipse虽然用的比较少,但是在一些古老的项目上还会用到滴,其中最麻烦的事情就是打带签名包的问题,不太方便,下面通过本文给大家记录下配置ant,自动打包带签名apk的过程,作为备份.(PC环境为MAC) 1,第一步得安ant,下载对应安装包,解压后配置环境变量: export ANT_HOME="/Users/yanzi/work/apache-ant-1.9.4" export PATH=${PATH}:${ANT_HOME}/bin 通过which ant检查是否安装成功. 2

  • 常用数字签名算法RSA与DSA的Java程序内实现示例

    RSA加密算法 我们来回顾一下RSA的加密算法.我们从公钥加密算法和签名算法的定义出发,用比较规范的语言来描述这一算法. RSA公钥加密体制包含如下3个算法:KeyGen(密钥生成算法),Encrypt(加密算法)以及Decrypt(解密算法). 密钥生成算法以安全常数作为输入,输出一个公钥PK,和一个私钥SK.安全常数用于确定这个加密算法的安全性有多高,一般以加密算法使用的质数p的大小有关.越大,质数p一般越大,保证体制有更高的安全性.在RSA中,密钥生成算法如下:算法首先随机产生两个不同大质

  • Java加密和数字签名编程

    本文主要谈一下密码学中的加密和数字签名,以及其在java中如何进行使用.对密码学有兴趣的伙伴,推荐看Bruce Schneier的著作:Applied Crypotography.在jdk1.5的发行版本中安全性方面有了很大的改进,也提供了对RSA算法的直接支持,现在我们从实例入手解决问题(本文仅是作为简单介绍): 一.密码学上常用的概念 1)消息摘要: 这是一种与消息认证码结合使用以确保消息完整性的技术.主要使用单向散列函数算法,可用于检验消息的完整性,和通过散列密码直接以文本形式保存等,目前

  • Java2下Applet数字签名

    我的项目是使用APPLET制作一个实时消息队列监控程序,由于涉及到了本地资源,对APPLET一定要进行数字签名和认证.我使用的环境是WINDOWS2000,应用服务器是WEBLOGIC6.0,开发环境是JBUILDER4.0.之前我提醒大家一定要注意服务器端和客户端的概念.那些文件应该在服务器端,那些文件应该在客户端. 首先在客户端使用JRE1.3.0_01(JAVA运行环境1.3.0.1版本)以取代IE的JVM(JAVA虚拟机),可以到WWW.JAVA.SUN.COM网站上去下载,下载好了先在

  • Java实现的数字签名算法RSA完整示例

    本文实例讲述了Java实现的数字签名算法RSA.分享给大家供大家参考,具体如下: 一 背景介绍 数字签名:带有密钥(公钥.私钥)的消息摘要算法. 验证数据完整性.认证数据来源.抗否认. 私钥签名.公钥验证. 常用算法:RSA.DSA.ECDSA 二 RSA介绍 包括MD和SHA两类 三 Java代码实现 package com.imooc.security.rsa2; import java.security.KeyFactory; import java.security.KeyPair; i

  • Android APK使用Debug签名重新打包 Eclipse更改默认Debug签名

    对已有的apk文件进行重新打包,前面 Android签名机制:生成keystore.签名.查看签名信息 已经介绍了.本文介绍另外两种需求. 使用默认的Debug签名打包 如果直接使用Eclipse开发新程序,默认就会被打上Debug的签名,这个是地球人皆知,但是如果你是想Repack别人并且想使用Debug签名该怎么办? 首先需要找到你本机的默认签名的,一般位于C:\Users\用户名\.android\debug.keystore下,拷出来,然后打包,打包命令: 复制代码 代码如下: jars

  • 解决在eclipse中将android项目生成apk并且给apk签名的实现方法详解

    生成apk最懒惰的方法是:只要你运行过android项目,到工作目录的bin文件夹下就能找到与项目同名的apk文件,这种apk默认是已经使用debug用户签名的.如果想要自己给apk签名:1.签名的意义为了保证每个应用程序开发商合法ID,防止部分开放商可能通过使用相同的Package Name来混淆替换已经安装的程序,我们需要对我们发布的APK文件进行唯一签名,保证我们每次发布的版本的一致性(如自动更新不会因为版本不一致而无法安装).2.签名的步骤a.创建keyb.使用步骤a中产生的key对ap

  • 使用数字签名实现数据库记录防篡改(Java实现)

    本文大纲 一.提出问题 二.数字签名 三.实现步骤 四.参考代码 五.后记 六.参考资料 一.提出问题 最近在做一个项目,需要对一个现成的产品的数据库进行操作,增加额外的功能.为此,需要对该产品对数据库有什么操作进行研究(至于怎么监控一个产品的操作会引发什么数据库操作,以后会详细解说).本来已经对数据库的操作了如指掌的,无意中发现数据库表里的每条记录都会有这样一个字段: 这感觉不妙了,字段名叫signature,顾名思义,就是签名的意思呀.难道数据库表中的每条记录都会有签名?也就是说如果我不能正

随机推荐