JAVA加密算法数字签名实现原理详解

所谓数字签名就是信息发送者用其私钥对从所传报文中提取出的特征数据(或称数字指纹)进行 RSA 算法操作,以保证发信人无法抵赖曾发过该信息(即不可抵赖性),同时也确保信息报文在经签名后末被篡改(即完整性)。当信息接收者收到报文后,就可以用发送者的公钥对数字签名进行验证。

在数字签名中有重要作用的数字指纹是通过一类特殊的散列函数(HASH 函数)生成的,对这些 HASH 函数的特殊要求是:

1:接受的输入报文数据没有长度限制;

2:对任何输入报文数据生成固定长度的摘要(数字指纹)输出

3:从报文能方便地算出摘要;

4:难以对指定的摘要生成一个报文,而由该报文反推算出该指定的摘要;

5:两个不同的报文难以生成相同的摘要

代表:DSA

代码如下

package test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
public class DSA {
	public static void main(String[] args) {
		try {
			DSA my = new DSA();
			my.run();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public void run() {
		// 数字签名生成密钥
		// 第一步生成密钥对,如果已经生成过 , 本过程就可以跳过
		// 对用户来讲 myprikey.dat 要保存在本地,而 mypubkey.dat 给发布给其它用户
		if ((new java.io.File("myprikey.dat")).exists() == false) {
			if (generatekey() == false) {
				System.out.println("生成密钥对败");
				return;
			}
		}
		// 第二步 , 此用户
		// 从文件中读入私钥 , 对一个字符串进行签名后保存在一个文件 (myinfo.dat) 中
		// 并且再把 myinfo.dat 发送出去,为了方便数字签名也放进了 myifno.dat 文件中 , 当然也可分别发送
		try {
			ObjectInputStream in = new ObjectInputStream(new FileInputStream("myprikey.dat"));
			PrivateKey myprikey = (PrivateKey) in.readObject();
			in.close();
			String myinfo = "这是我的信息"; // 要签名的信息
			// 用私钥对信息生成数字签名
			Signature signet = Signature.getInstance("DSA");
			signet.initSign(myprikey);
			signet.update(myinfo.getBytes());
			byte[] signed = signet.sign(); // 对信息的数字签名
			System.out.println("signed( 签名内容 )=" + byte2hex(signed));
			// 把信息和数字签名保存在一个文件中
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("myinfo.dat"));
			out.writeObject(myinfo);
			out.writeObject(signed);
			out.close();
			System.out.println("签名并生成文件成功");
		} catch (java.lang.Exception e) {
			e.printStackTrace();
			System.out.println("签名并生成文件失败");
		}
		// 第三步 获得信息检查
		// 其他人通过公共方式得到此户的公钥和文件
		// 其他人用此户的公钥 , 对文件进行检查 , 如果成功说明是此用户发布的信息 .
		try {
			ObjectInputStream in = new ObjectInputStream(new FileInputStream("mypubkey.dat"));
			PublicKey pubkey = (PublicKey) in.readObject();
			in.close();
			System.out.println(pubkey.getFormat());
			in = new ObjectInputStream(new FileInputStream("myinfo.dat"));
			String info = (String) in.readObject();
			byte[] signed = (byte[]) in.readObject();
			in.close();
			Signature signetcheck = Signature.getInstance("DSA");
			signetcheck.initVerify(pubkey);
			signetcheck.update(info.getBytes());
			if (signetcheck.verify(signed)) {
				System.out.println("info=" + info);
				System.out.println("签名正常");
			} else
				System.out.println("非签名正常");
		} catch (java.lang.Exception e) {
			e.printStackTrace();
		}
		;
	}
	// 生成一对文件 myprikey.dat 和 mypubkey.dat 私钥和公钥
	// 公钥要用户发送 ( 文件 , 网络等方法 ) 给其它用户 , 私钥保存在本地
	public boolean generatekey() {
		try {
			KeyPairGenerator keygen = KeyPairGenerator.getInstance("DSA");
			keygen.initialize(512);
			KeyPair keys = keygen.genKeyPair();
			PublicKey pubkey = keys.getPublic();
			PrivateKey prikey = keys.getPrivate();
			ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("myprikey.dat"));
			out.writeObject(prikey);
			out.close();
			System.out.println("写入对象 prikeys ok");
			out = new ObjectOutputStream(new FileOutputStream("mypubkey.dat"));
			out.writeObject(pubkey);
			out.close();
			System.out.println("写入对象 pubkeys ok");
			System.out.println("生成密钥对成功");
			return true;
		} catch (java.lang.Exception e) {
			e.printStackTrace();
			System.out.println("生成密钥对失败");
			return false;
		}
	}
	public String byte2hex(byte[] b) {
		String hs = "";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
			if (n < b.length - 1)
				hs = hs + ":";
		}
		return hs.toUpperCase();
	}
}

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

(0)

相关推荐

  • 浅析java消息摘要与数字签名

    消息摘要 算法简述 定义 它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生.如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了.因此消息摘要保证了消息的完整性.消息摘要采用单向Hash 函数将需加密的明文"摘要"成一串密文,这一串密文亦称为数字指纹(Finger Print).它有固定的长度,且不同的明文摘要成密文,其结果总是不同的,而同样的明文其摘要必定一致.这样这串摘要便可成为验证明文是否是

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

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

  • 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数字签名提供XML安全

    用Java数字签名提供XML安全 众所周知,XML在产品和项目开发中起着非常重要的作用.通过XML文档可以获取很多信息,还可以使用XML文件进行CRUD(增加.查询.更新和 删除)操作.然而值得注意的是,我们如何确保XML中的数据是来自经过认证的可信和可靠的来源.关于XML文件数据的可靠性和真实性存在很多问题.通常的 情况是,开发者直接处理XML文件而不去考虑数据的可靠性.有一些情况提出了上面的所有问题.现实生活中,每当我们从邮局收到一封信件时我们如何确定这封 信是来自我们的朋友?依据可能是他/

  • 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

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

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

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

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

  • 纯Java实现数字证书生成签名的简单实例

    package com.ylsoft.cert; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator;

  • Java加密和数字签名编程

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

  • JAVA加密算法数字签名实现原理详解

    所谓数字签名就是信息发送者用其私钥对从所传报文中提取出的特征数据(或称数字指纹)进行 RSA 算法操作,以保证发信人无法抵赖曾发过该信息(即不可抵赖性),同时也确保信息报文在经签名后末被篡改(即完整性).当信息接收者收到报文后,就可以用发送者的公钥对数字签名进行验证. 在数字签名中有重要作用的数字指纹是通过一类特殊的散列函数(HASH 函数)生成的,对这些 HASH 函数的特殊要求是: 1:接受的输入报文数据没有长度限制: 2:对任何输入报文数据生成固定长度的摘要(数字指纹)输出 3:从报文能方

  • Java中synchronized实现原理详解

    记得刚刚开始学习Java的时候,一遇到多线程情况就是synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字"同步",也成为了我们解决多线程情况的百试不爽的良药.但是,随着我们学习的进行我们知道synchronized是一个重量级锁,相对于Lock,它会显得那么笨重,以至于我们认为它不是那么的高效而慢慢摒弃它. 诚然,随着Javs SE 1.6对synchronized进行的各种优化后,synchronized并不会显得那么

  • Java静态static关键字原理详解

    这篇文章主要介绍了Java静态static关键字原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 static关键字既可以修饰成员变量,也可以修改成员方法,修饰的成员变量和成员方法可以直接通过类名调用,也可以通过对象调用(其实即使是通过对象调用,也会被翻译成类名调用),建议通过类名调用. 成员方法用static修饰后,就成为了静态方法,静态方法不属于对象,而是属于类. 注意事项: 1.静态方法中不能使用this,因为this指的是当前对象

  • Java多线程 线程状态原理详解

    这篇文章主要介绍了Java多线程 线程状态原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 java.lang.Thread.State枚举定义了6种线程状态. NEW: 尚未启动(start)的线程的线程状态 RUNNABLE: 运行状态,但线程可能正在JVM中执行,也可能在等待CPU调度 BLOCKED: 线程阻塞,等待监视器锁以进入同步代码块/方法 WAITING: 等待状态.使用以下不带超时的方式时会进入:Object.wait.

  • Java接口和抽象类原理详解

    这篇文章主要介绍了Java接口和抽象类原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太多不同的地方.很多人在初学的时候会以为它们可以随意互换使用,但是实际则不然.今天我们就一起来学习一下Java中的接口和抽象类.下面是本文的目录大纲: 一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一

  • Java钩子方法概念原理详解

    这篇文章主要介绍了Java钩子方法概念原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 钩子方法源于设计模式中模板方法(Template Method)模式,模板方法模式的概念为:在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤.其主要分为两大类:模版方法和基本方法,而基本方法又分为:抽象方法(Abstract Method),具体方法(Concrete Me

  • Java String 拼接字符串原理详解

    首先来一道思考题: String str1 = "111111"; String str2 = "222222"; String str = str1 + str2; System.out.println(str); 很明确,上述代码输出的结果是:"111111222222",但是它工作原理是怎样的呢? 由于字符串拼接太常用了,java才支持可以直接用+号对两个字符串进行拼接.**其真正实现的原理是中间通过建立临时的StringBuilder对象

  • Java SpringBoot自动装配原理详解及源码注释

    目录 一.pom.xml文件 1.父依赖 2.启动器: 二.主程序: 剖析源码注解: 三.结论: 一.pom.xml文件 1.父依赖 主要是依赖一个父项目,管理项目的资源过滤以及插件! 资源过滤已经配置好了,无需再自己配置 在pom.xml中有个父依赖:spring-boot-dependencies是SpringBoot的版本控制中心! 因为有这些版本仓库,我们在写或者引入一些springboot依赖的时候,不需要指定版本! 2.启动器: 启动器也就是Springboot的启动场景; 比如sp

  • Java NIO Buffer实现原理详解

    目录 1.Buffer的继承体系 2.Buffer的操作API使用案例 3.Buffer的基本原理 4.allocate方法初始化一个指定容量大小的缓冲区 5.slice方法缓冲区分片 6.只读缓冲区 7.直接缓冲区 8.内存映射 1.Buffer的继承体系 如上图所示,对于Java中的所有基本类型,都会有一个具体的Buffer类型与之对应,一般我们最经常使用的是ByteBuffer. 2.Buffer的操作API使用案例 举一个IntBuffer的使用案例: /** * @author csp

  • java Spring的启动原理详解

    目录 引入 Spring启动过程 总结: 总结 引入 为什么突然说一下Spring启动原理呢,因为之前面试的时候,回答的那可谓是坑坑洼洼,前前后后,补补贴贴... 总而言之就是不行,再次看一下源码发掘一下... 在Spring Boot还没有广泛到家家在用的时候,我们都还在书写繁琐的配置,什么web.xml.spring.xml.bean.xml等等.虽然现在很少,可以说几乎没有企业在去使用Spring的老一套,而会去使用Spring Boot约定大于配置来进行快速开发,但是,Spring的也要

随机推荐