用Java实现数字签名

合集下载

java 加签方法

java 加签方法

java 加签方法Java加签方法Java加签是在数据传输过程中,为数据增加一段签名,以验证数据的完整性和真实性。

在Java中,可以通过使用MessageDigest类和PrivateKey类实现加签功能。

下面将介绍如何使用Java中的加签方法。

首先,我们需要获取要加签的数据。

假设我们有一个字符串类型的数据,如下所示:```javaString data = "Hello, World!";```接下来,我们需要准备私钥,私钥用于生成签名。

私钥可以由数字证书颁发机构(CA)或其他合法机构颁发。

假设我们已经有一个私钥文件 privateKey.pem,我们可以使用下面的代码读取私钥:```javaString privateKeyPath = "path/to/privateKey.pem";String privateKeyContent = newString(Files.readAllBytes(Paths.get(privateKeyPath)));```然后,我们需要将私钥转换为Java中的PrivateKey对象。

我们可以使用Java的密钥工厂(KeyFactory)类来实现转换:```javaString privateKeyType = "RSA";PKCS8EncodedKeySpec keySpec = newPKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKeyContent));PrivateKey privateKey =KeyFactory.getInstance(privateKeyType).generatePrivate(keySpec);```接下来,我们使用私钥对数据进行加签。

通常使用RSA算法进行签名。

我们可以使用Java的Signature类来实现加签功能:```javaString algorithm = "SHA256withRSA";Signature signature = Signature.getInstance(algorithm);signature.initSign(privateKey);signature.update(data.getBytes());byte[] sign = signature.sign();```现在,我们已经生成了加签后的数据。

java 签章流程

java 签章流程

Java签章流程介绍在现代数字化的时代,电子签名已经成为了一种普遍的方式来确认文件的真实性和完整性。

Java提供了丰富的API和工具来实现电子签名功能。

本文将详细介绍Java签章的流程和步骤,以确保流程清晰且实用。

签章流程Java签章的流程可以分为以下几个步骤:1.准备工作:在开始签章之前,需要准备一些必要的工作,包括获取证书、创建密钥库等。

2.加载证书:需要加载用于签章的证书。

证书是由认证机构(CA)颁发的,用于验证签名者身份和确保文件的完整性。

3.创建数字签名:使用私钥对文件进行加密生成数字签名。

私钥是与公钥配对使用的密钥,只有持有私钥的人才能对文件进行数字签名。

4.将数字签名附加到文件:将生成的数字签名附加到原始文件中。

这可以通过在文件中添加特定标记或在文件末尾添加附加信息来完成。

5.验证数字签名:接收者可以使用公钥来验证文件的数字签名是否有效。

公钥是与之前加载的证书相关联的密钥。

下面将详细介绍每个步骤。

准备工作在开始签章之前,需要进行一些准备工作。

1.获取证书:需要获取一个由认证机构颁发的证书。

可以通过向认证机构申请或购买来获得。

2.创建密钥库:密钥库是用于存储私钥和相关证书的安全文件。

可以使用Java提供的keytool工具来创建密钥库。

以下是创建密钥库的示例命令:keytool -genkeypair -alias mykey -keyalg RSA -keystore keystore.jks这将创建一个名为keystore.jks的密钥库,并生成一个RSA算法的密钥对。

3.导出证书:从生成的密钥库中导出公钥证书。

可以使用以下命令导出证书:keytool -exportcert -alias mykey -keystore keystore.jks -file certificate.crt这将从keystore.jks中导出名为certificate.crt的证书文件。

加载证书在准备工作完成后,可以加载用于签章的证书。

签名加密_Java_hutool(01代码实现)

签名加密_Java_hutool(01代码实现)

签名加密_Java_hutool(01代码实现) 本⽂档不讲解签名/加密相关的理论知识, 仅列出通过Java实现的⽅式.对称加密加解密使⽤的是同⼀个秘钥基于“对称密钥”的加密算法主要有DES、3DES(TripleDES)、AES、RC2、RC4、RC5和Blowfish等。

本⽂只介绍最常⽤的对称加密算法DES、3DES(TripleDES)和AES。

⾮对称加密加解密使⽤的是不同的秘钥基于“⾮对称密钥”的加密算法主要有RSA、Elgamal、背包算法、Rabin、D-H、ECC(椭圆曲线加密算法)。

使⽤最⼴泛的是RSA算法,Elgamal是另⼀种常⽤的⾮对称加密算法。

使⽤场景在互联⽹后端技术中⾮对称加密技术主要⽤于登录、数字签名、数字证书认证等场景。

疑问: 既然堆成加密存在安全问题, 为什么还使⽤对称加密呢? ( 我同事告诉我, 当前功能不开放到外⽹, 使⽤对称加密即可 )使⽤到的依赖包hutool<!-- https:///artifact/cn.hutool/hutool-all --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>4.6.1</version></dependency>AES对称加密/解密public String encryptAES(String data, String key) throws Exception {//⽣成⼀个随机秘钥//byte[] keyRandom = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();//将秘钥转为Base64//String keyRandomEncode = Base64.encode(keyRandom);key = "EC/Z+S7c3EFJa2dtvLyekg==";//将Base64编码的秘钥的格式进⾏解码转换byte[] keyByte = Base64.decode(key);//加密AES aes = SecureUtil.aes(keyByte); //构建byte[] encryptData = aes.encrypt(data); //加密//加密后的数据转为Base64String encryptDataEncode = Base64.encode(encryptData);//将Base64编码加密数据和秘钥的格式进⾏解码转换byte[] data2 = Base64.decode(encryptDataEncode);byte[] key2 = Base64.decode(key);//解密AES aes2 = SecureUtil.aes(key2);byte[] decrypt = aes.decrypt(data2);return "秘钥: "+ key + ", 加密后的数据: "+ encryptDataEncode + ", 解密后的数据: "+ new String (decrypt);}其他@Override public String dataSign(MsgForm msgForm) throws Exception {String ywData = msgForm.getData();String prikeyYlf = msgForm.getPrivateKey();msgForm.getKeyLen();Sign sign = new Sign(SignAlgorithm.SHA1withRSA, prikeyYlf, null);byte[] encrypt = sign.sign(StrUtil.bytes(ywData, CharsetUtil.CHARSET_UTF_8));return Base64.encode(encrypt);}@Override public boolean verifySign(MsgForm msgForm) throws Exception {String ywData = msgForm.getData();String signData = msgForm.getSignData();String publicKey = msgForm.getPublicKey();msgForm.getKeyLen();Sign sign = new Sign(SignAlgorithm.SHA1withRSA, null, publicKey);boolean encrypt = sign.verify(StrUtil.bytes(ywData), Base64.decode(signData));//return Base64.encode(encrypt);return encrypt;}@Override public String encrypt(MsgForm msgForm) throws Exception {RSA rsa = new RSA(null, msgForm.getPublicKey());byte[] encrypt = rsa.encrypt(StrUtil.bytes(msgForm.getData(), CharsetUtil.CHARSET_UTF_8), KeyType.PublicKey);return Base64.encode(encrypt);}@Override public String decrypt(MsgForm msgForm) throws Exception {RSA rsa = new RSA(msgForm.getPrivateKey(), null);byte[] decrypt = rsa.decrypt(Base64.decode(msgForm.getData()), KeyType.PrivateKey);return Base64.encode(decrypt);}@Override public void dataReceive(MsgForm msgForm) throws Exception {SimpleDateFormat ft = new SimpleDateFormat("yyyyMMddHHmmsszzz");StringBuffer filePath = new StringBuffer(Config.getProperty("download.path"));filePath.append("99_");filePath.append(msgForm.getBusiCode()+"_"); //业务类型(6)filePath.append(ft.format(new Date())+"_"); //yyyyMMddhhmisszzz(17)filePath.append(new Random().nextInt(10)); //2位随机数filePath.append(new Random().nextInt(10));filePath.append(".XML"); //.XML//将数据写⼊到filePathFileWriter fw = new FileWriter(filePath.toString(),"UTF-8");byte[] pdfData = Base64.decode(msgForm.getData());fw.write(pdfData,0,pdfData.length);}@Override public String encryptAES(String data, String key) throws Exception {//⽣成⼀个随机秘钥//byte[] kkkkRandom = SecureUtil.generateKey(SymmetricAlgorithm.AES.getValue()).getEncoded();//将秘钥转为Base64//key = Base64.encode(kkkkRandom);//key = "7Df05RgSzVm8/wWzUeTDaA==";//将Base64编码的秘钥的格式进⾏解码转换byte[] keyByte = Base64.decode(key);//加密AES aes = SecureUtil.aes(keyByte); //构建byte[] encryptData = aes.encrypt(data); //加密//加密后的数据转为Base64return Base64.encode(encryptData);}@Override public String decryptAES(String data, String key) throws Exception {//key = "7Df05RgSzVm8/wWzUeTDaA==";//将Base64编码加密数据和秘钥的格式进⾏解码转换byte[] dataByte = Base64.decode(data);byte[] keyByte = Base64.decode(key);//解密AES aes = SecureUtil.aes(keyByte); //构建byte[] decrypt = aes.decrypt(dataByte); //加密return new String (decrypt); //转换为字符串返回}。

基于JAVA的数字签名设计与实现

基于JAVA的数字签名设计与实现

其 中 k 1 H M)= ,<kl q (s构成 了对信 息 M 的数 - ( ( q I0 -< ,r) ,
字签名 。
() 2 验证 。信 息接收 方收到 M、 和 S , 算 u =H M) r 后 计 l((
w) dqu =—w) d , mo ,2 f mo q
其 中 , = ・ro ,=( u *u ) d ) dq w s1 dq v (g ly 2mo pmo ,如 果 v r o =,
() 1 发送 方用一个 Hah函数对 报文进行 处理 , 生消息 s 产
则判断数字签 名是有效的。
3 基 于, V . J A的数 字 签 名设 计 A
在数 据签名 的设计 实现方面 , H 、 B、aa均 能有较 C V Jv
地实现 , 作为应用普遍的 Jv aa编程语言 , 通过其提供 的密钥管 理、 认证 、 加密、 数字签名和存取控制功能,a a Jv 编程语 言提供
P 素 数 , 中 2 .< < L52 L 12 , L是 6 : 其 L 1p 2 ,1< < 0 4且 4的 倍数 ;
在网络信息传输 中,对信 息进行加密可 以保 证信 息的机 密性 。但: 网是一个完全开放的环境 , 巨联 在基于 It n t ne e 的计 r 算机网络在线信息系统,还需要用 一种机制来对通信双 方的 身份进行认证 , 以保证系统的安全 。数字签名是基于公开密钥 加密体制的 。在公开密钥加密体制 下, 加密密钥是公开 的, 保 密性完全取决于解密密钥, 即私有密钥 的保密 。从另一个角度
摘要 进 行 D A S
学、在线 考试等信息系统作为一种新的应用形式应用越来越
算法计算, 产生数字签名, 并实现报文和数字签名共 同发送 ;

java 国密加签验签流程

java 国密加签验签流程

java 国密加签验签流程Java国密加签验签流程国密算法是我国自主研发的密码算法标准,具有高安全性和高效率的特点。

在Java中使用国密算法进行加签验签操作可以保障数据的安全性。

下面将介绍Java国密加签验签的流程。

一、加签流程1. 导入相关的类库在Java代码中,首先需要导入国密算法相关的类库。

可以使用Bouncy Castle库来实现国密算法的加签验签操作。

2. 初始化密钥使用国密算法进行加签验签操作时,首先需要初始化密钥。

可以通过KeyPairGenerator类生成密钥对,其中包括公钥和私钥。

3. 加载私钥在进行加签操作之前,需要加载私钥。

可以通过KeyFactory类的generatePrivate方法将密钥字节数组转换为私钥对象。

4. 创建签名对象使用Signature类创建签名对象,通过调用其getInstance方法并指定国密算法类型来创建签名对象。

在进行加签操作之前,需要初始化签名对象。

可以通过调用Signature类的initSign方法并传入私钥对象来初始化签名对象。

6. 更新数据对需要进行加签的数据进行更新。

可以通过Signature类的update方法传入数据字节数组来更新数据。

7. 签名使用Signature类的sign方法进行签名操作,将加签结果保存为字节数组。

二、验签流程1. 导入相关的类库同样需要导入国密算法相关的类库。

2. 加载公钥在进行验签操作之前,需要加载公钥。

可以通过KeyFactory类的generatePublic方法将公钥字节数组转换为公钥对象。

3. 创建签名对象使用Signature类创建签名对象,通过调用其getInstance方法并指定国密算法类型来创建签名对象。

在进行验签操作之前,需要初始化签名对象。

可以通过调用Signature类的initVerify方法并传入公钥对象来初始化签名对象。

5. 更新数据对需要进行验签的数据进行更新。

可以通过Signature类的update方法传入数据字节数组来更新数据。

java 验签的原理

java 验签的原理

java 验签的原理
在Java中,验签(Verification Signature)是指对数字签名进行验证,以确保传输的数据的完整性和真实性。

数字签名是使用私钥生成的加密摘要,用于验证数据的完整性和发送者的身份。

下面是Java中验签的基本原理:
1.数字签名生成:首先,在数据发送者端,使用私钥对数据
进行加密摘要的生成(签名)操作。

一般来说,使用的加
密算法是非对称加密算法,如RSA。

2.数据传输:接着,将数据和数字签名一起传输给接收者。

数据可以是文件、消息或其他形式的信息。

3.数字签名验证:在数据接收者端,接收到数据和数字签名
后,使用发送者的公钥对数字签名进行验证。

公钥是非对
称加密算法中与私钥对应的,可以用于解密数字签名。

4.验签结果:通过对数字签名的验证,接收者可以得到验签
结果。

如果数字签名验证通过,则表示数据的完整性未被
篡改,并且发送者的身份得到确认。

Java提供了相关的加密库和工具类来支持数字签名的生成和验证,如Java Cryptography Architecture(JCA)和相关的API,如java.security.Signature和java.security.KeyPair等类。

在验签过程中,关键是使用正确的公钥对数字签名进行验证。

公钥需要通过安全信道获得,以确保公钥的真实性和完整性。

此外,还需确保私钥的安全保存,以防止私钥泄露导致签名被
伪造。

java验签方法

java验签方法一、概述Java验签是指对数字签名进行验证的过程,是保证数字签名的真实性、完整性和不可抵赖性的重要手段。

Java提供了许多工具类和方法来实现数字签名的生成和验证,本文将详细介绍Java验签的方法。

二、数字签名数字签名是指用私钥对原始数据进行加密生成的一段数据,用于保证原始数据的真实性、完整性和不可抵赖性。

数字签名包含两部分:原始数据和加密后的数据。

在生成数字签名时,使用私钥对原始数据进行加密得到加密后的数据,并将原始数据和加密后的数据组合成一个字符串作为数字签名。

三、数字证书在进行数字签名时,需要使用到数字证书。

数字证书是一种由权威机构颁发并包含公钥信息以及其他身份信息的电子文档。

在进行数字签名时,需要使用到私钥对原始数据进行加密,而私钥是保存在本地计算机或设备中,并且需要密码保护。

因此,在向外提供服务或者验证身份时,需要使用公钥来验证身份或者验证数字签名。

四、Java验签方法1. 获取公钥首先需要获取公钥信息,在Java中可以通过以下代码获取:KeyStore keyStore = KeyStore.getInstance("JKS"); keyStore.load(new FileInputStream("keystore.jks"), "password".toCharArray());Certificate certificate = keyStore.getCertificate("alias"); PublicKey publicKey = certificate.getPublicKey();其中,JKS是Java Key Store的缩写,是Java中用于存储密钥和证书的一种格式。

keystore.jks是存储公钥和私钥的文件名,alias是存储在keystore中的别名。

2. 验证数字签名获取公钥之后,就可以使用公钥来验证数字签名。

使用JAVA生成MD5编码

使⽤JAVA⽣成MD5编码MD5即Message-Digest Algorithm 5(信息-摘要算法5),是⼀种⽤于产⽣数字签名的单项散列算法,在1991年由MIT Laboratory for Computer Science(IT计算机科学实验室)和RSA Data Security Inc(RSA数据安全公司)的Ronald L. Rivest教授开发出来,经由MD2、MD3和MD4发展⽽来。

MD5算法的使⽤不需要⽀付任何版权费⽤。

它的作⽤是让⼤容量信息在⽤数字签名软件签私⼈密匙前被"压缩"成⼀种保密的格式(将⼀个任意长度的“字节串”通过⼀个不可逆的字符串变换算法变换成⼀个128bit的⼤整数,换句话说就是,即使你看到源程序和算法描述,也⽆法将⼀个MD5的值变换回原始的字符串,从数学原理上说,是因为原始的字符串有⽆穷多个,这有点象不存在反函数的数学函数。

)在 Java 中,java.security.MessageDigest 中已经定义了 MD5 的计算,所以我们只需要简单地调⽤即可得到 MD5 的128 位整数。

然后将此 128 位计 16 个字节转换成 16 进制表⽰即可。

代码如下:/**** <p>* Created on 2011-11-25* </p>*/package com.util;import java.io.UnsupportedEncodingException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/*** 功能:MD5加密算法* 公司名称:夏影* 修改时间:2011-11-15*/public class Md5Encrypt {/*** Used building output as Hex*/private static final char[] DIGITS = { '0', '1', '2', '3', '4', '5', '6','7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };/*** 对字符串进⾏MD5加密** @param text* 明⽂** @return密⽂*/public static String md5(String text) {MessageDigest msgDigest = null;try {msgDigest = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {throw new IllegalStateException("System doesn't support MD5 algorithm.");}try {msgDigest.update(text.getBytes("GBK")); //这个加密算法是按照GBK编码进⾏加密} catch (UnsupportedEncodingException e) {throw new IllegalStateException("System doesn't support your EncodingException.");}byte[] bytes = msgDigest.digest();String md5Str = new String(encodeHex(bytes));return md5Str;}public static char[] encodeHex(byte[] data) {int l = data.length;char[] out = new char[l << 1];// two characters form the hex value.for (int i = 0, j = 0; i < l; i++) {out[j++] = DIGITS[(0xF0 & data[i]) >>> 4];out[j++] = DIGITS[0x0F & data[i]];}return out;}}测试代码如下:package com.util;public class TestMD5 {public static void main(String[] args) {// 计算 "a" 的 MD5 代码,应该为:0cc175b9c0f1b6a831c399e269772661System.out.println(Md5Encrypt.md5("a"));}}MD5的典型应⽤是对⼀段Message(字节串)产⽣fingerprint(指纹),以防⽌被"篡改"。

网络安全技术应用——数字签名技术在Java中的实现


图 1 公开 密钥加 密体制
的作用 。 字 签名 在I tr e k 数 n en t 的应 用 需 要专 门 的数 字证 书 颁 发认 证机 _ 构, 统一 管 理数 字 签名的 应用 和校 验 。 字签 名可以 解 决否 认、 数 伪造 、 篡 改及冒充等 问题 。 体要 求 : 送者 事后不 能否认 发 送 的报文 签名 , 具 发 接收 者 能够 核 实发送 者 发送 的报 文签 名 , 收者 不能 对发 送 者 的报 文进 行部 接 分篡 改 , 网络 中的 某一 用户不能 冒充 另一用户 作为发 送者获 接 收者 。 数字 签名 的应 用范 围十 分广泛 , 保 障电子 数据 交换 的 安全 性 上 是一 个 突破 在 性 的进 展 , 凡需要 对用 户的 身份 进行 判 断 的情 况都 可 以使 用数 字 签名以 确 保数 据 的完 整 性 、 私有性 和 不 可抵 赖性 。 文讨 论 了数 字 签名 技 术的 本
原理 , 介 绍 了使用Jv 语言 实现 数字 签名的 一种方 法 。 并 aa 2 数字 签名技 术 、 21 . 公开 密钥加 密 体制 22 . 数字 签名
数字 签名技 术 以公开 密 钥加 密技 术为 基础 . 核心 是采 用加 密技 术 其 的加 、 密 算 法体 制来 实 现对 信息 的 数字 签名 。签名机 制 的本 质特 征 是 解 该签名 只用通 过 签名者 的私有 信息才 能产 生. 就 是说 . 个 签名者 的签 也 一 名只 能唯一 的 由他 自己产 生 。 当收 发 双方发 生争 议时 , 三 方( 裁 机构 ) 第 仲
程如 下: ຫໍສະໝຸດ 收者不需要共享一个密钥. 在通信的全部过程中不需要传送秘密密钥。
公开密 钥算 法的主 要特 点如下 : () 密密 钥P 1用加 K对 明文 AJ密后 得 到密 文 , }l t 再用 解密 密 钥S K对密 文解密 , 即可恢 复出明文A, : EA) A 即 D(( ) = () 密 密钥 不能用 来解 密, : P E KA) ̄ D EA) A 2 加 即 D K(P ( ) A, ( ( ) ≠ () K/密 的信 息只 能用 P 3用S JI I K解密 , K加 密 的信 息 只能用 S 用P K解

java点名签到功能实现方法

java点名签到功能实现方法在Java中实现一个点名签到功能,你需要考虑几个关键的步骤。

以下是一个简单的实现方法:1. 设计数据库结构:首先,你需要一个数据库来存储学生的信息。

这个数据库至少应该包含学生的姓名和是否已经签到的信息。

2. 建立数据库连接:使用Java的JDBC(Java Database Connectivity)库来连接你的数据库。

3. 编写签到逻辑:当学生尝试签到时,你需要检查他们是否已经签到。

如果已经签到,则不做任何事情;如果尚未签到,则更新数据库中的状态并标记他们已签到。

下面是一个简单的代码示例,这个示例使用Java和JDBC来连接到MySQL 数据库,并实现一个基本的点名签到功能:```javaimport ;import ;import ;import ;public class AttendanceSystem {private static final String DB_URL = "jdbc:private static final String USER = "root";private static final String PASS = "password";public static void main(String[] args) {String studentName = "John Doe"; // 学生姓名checkAttendance(studentName);}public static void checkAttendance(String studentName) {try {Connection conn = (DB_URL, USER, PASS);String query = "SELECT FROM students WHERE name = ?"; PreparedStatement pstmt = (query);(1, studentName);ResultSet rs = ();if (()) {boolean isPresent = ("is_present");if (!isPresent) {updateAttendance(studentName);} else {(studentName + " has already checked in.");}} else {("Student not found in the system.");}();();();} catch (Exception e) {();}}public static void updateAttendance(String studentName) { try {Connection conn = (DB_URL, USER, PASS);String query = "UPDATE students SET is_present = true WHERE name = ?";PreparedStatement pstmt = (query);(1, studentName);int rowsAffected = ();if (rowsAffected > 0) {(studentName + " has been marked present.");} else {("No rows were affected.");}();();} catch (Exception e) {();}}}```在这个示例中,我们假设有一个名为`students`的表,其中包含学生的姓名和是否已经签到的信息。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

第 12 章 数据的加密保护
以下代码是用 Java 语言实现将一个字符串“郭克华_安全编程技术”,利用 DSA 算法 进行数字签名并且验证的过程,同样,由于本书不是讲解某种语言本身,所以在这里略过 Java 加密体系的讲解,在代码中如果出现新的 API,读者可以参考 Java 文档。
P12_02.java import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException;
x2x
第 12 章 数据的加密保护
(2) 将收到的消息摘要 H(M)用发送方公开密钥进行解密; (3) 两者进行比较,不一致则发出否决消息,否则接受信息。
〖2-1〗用RSA实现数字签名
以下代码是用 Java 语言实现将一个字符串“郭克华_安全编程技术”,利用 RSA 和 SHA 算法进行数字签名并且验证的过程,同样,由于本书不是讲解某种语言本身,所以在这里 略过 Java 加密体系的讲解,在代码中如果出现新的 API,读者可以参考 Java 文档。
在不同的情况下字签名
在第 12 章我们介绍了 DSA,数字签名算法(Digital Signature Algorithm ,DSA),它也是 一种非对称加密算法,被美国 NIST 作为数字签名标准(DigitalSignature Standard, DSS)。但 是 应用于数字签名中。DSA 算法比 RSA 产生密钥的速度要快一些,且安全性与 RSA 差 不多。DSA 的理论基础,主要依赖于整数有限域离散对数难题。关于其实现过程,读者可 以参考相关文献。 x4x
if(sig.verify(signatureBytes)) {
System.out.println("签名验证成功"); } else {
System.out.println("签名验证失败"); } } catch(SignatureException e) { e.printStackTrace(); } } } 运行,界面如下:
public class P14_01 {
public static void main(String[] args) throws Exception {
String msg = "郭克华_安全编程技术"; System.out.println("原文是:" + msg);
byte[] msgBytes = msg.getBytes();
〖1-2〗数字签名的过程
在数字签名方面,目前应用比较广泛的是利用 RSA 计算签名和数字签名标准 DSS。 其中,利用 RSA 方法进行数字签名得到了广泛的应用。该方法的过程如下:
1:要签名的报文作为一个散列函数的输入,产生一个定长的安全散列码,一般称为 消息摘要。
2:使用发方的私有密钥对这个消息摘要进行加密就形成签名。将报文和签名传送出 去。
h=H(M) 其中,M 是待加工的消息,可以为任意长度;H 为单向散列算法,h 作为生成的消息 摘要,具有固定的长度,并且和 M 的长度无关。一个好的单向散列算法需要 H 具有以下 的单向性质:①给定 H 和 M,很容易计算 h;②给定 h 和 H,很难计算 M,甚至得不到 M 的任何消息;③给定 H,要找两个不同的 M1 和 M2,使得 H(M1)= H(M2)在计算上是不可行 的。 在实际应用中还要求单向散列函数具有如下特点:(1)单向散列函数能够处理任意长度 的消息(至少是在实际应用中可能碰到的长度的消息),其生成的消息摘要长度具有固定的 大小,而且,对同一个消息反复执行该函数总得到相同的消息摘要。(2)单向散列函数生成 的消息摘要是不可预见的,消息摘要看起来和原始数据没有任何关系。而且,原始数据的 任何微小变化都会对生成的消息摘要产生很大的影响。(3)具有不可逆性,即通过生成的消 息摘要得到原始数据的任何信息在计算上是完全不可行的。 目前在密码学上已经设计出了大量的单向散列函数,如:RabinHash 方案、MerkleHash 方案、NHash 算法、MD2 算法、MD4 算法、MD5 算法和 SHA 等。通过考察发现,实际 系统中用得最多的单向散列函数是消息摘要算法 MD5(Message Digest5)和安全散列算法 SHA(Security Hash Algorithm)。它们具有相似的原理和实现方法,关于它们在不可逆加密 中的应用,前述章节已经叙述。
ChinaSEI系列讲义(By郭克华)
用 Java 实现数字签名
如果有文字等小错,请多包涵。在不盈利的情况下,欢迎免费传播。 版权所有.郭克华 本讲义经过修正、扩充,由清华大学出版社出版。 详细可查询 /51834 /product.aspx?product_id=20862469
发送方 私钥加密
消息摘要 密文
消息 正文
单向 散列
发送方 公钥解密
接收方
消息 摘要
比较,得出结论
消息 摘要
图 1 数字签名的基本过程
如前所述,数字签名算法一般分为两个步骤:产生消息摘要和生成数字签名。 首先,系统根据一定的单向加密算法计算出消息的消息摘要。 使用单向散列函数的目的是将任意长度的消息压缩成为某一固定长度的消息摘要。单 向散列函数又称为单向 Hash 函数,它不是加密算法,却在密码学中有着广泛的应用,与 各种加密算法有着密切的关系。它的模型为:
【2】实现数字签名
如前所述,数字签名过程中,在产生签名阶段,发送方至少要进行以下的计算: (1) 由消息 M 利用单向散列函数产生消息摘要 H(M); (2) 将产生的消息摘要 H(M)用发方的私有密钥进行加密。 在验证签名阶段,接收方也要进行以下的计算: (1) 由消息 M 利用单向散列函数产生消息摘要 H(M);
public class P14_02 {
private KeyPair key = null; Signature sig = null; public P14_02() throws NoSuchAlgorithmException {
// 形成DSA公钥对 KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA"); keyGen.initialize(1024); // 生成公钥和私钥对 key = keyGen.generateKeyPair(); // 实例化Signature,用于产生数字签名,指定用DSA算法 sig = Signature.getInstance("DSA"); }
x3x
安全编程技术
byte[] signatureBytes = sig.sign();
String signature = new String(signatureBytes); System.out.println("签名是:" + signature);
//使用公鈅验证 PublicKey publicKey = key.getPublic(); sig.initVerify(publicKey); //对msgBytes重新实施签名 sig.update(msgBytes); try {
P14_01.java import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.PrivateKey; import java.security.PublicKey; import java.security.Signature; import java.security.SignatureException;
x5x
安全编程技术
byte[] signatureBytes = sig.sign(); return signatureBytes; }
3:收方接受报文并根据报文产生一个消息摘要,同时使用发方的公开密钥对签名进 行解密。
4:如果计算得出的消息摘要和解密后的签名互相匹配,那么签名就是有效的。 5:因为只有发方知道密钥,因此只有发方才能产生有效的签名。 具体过程如下图所示:
安全编程技术
发送方
消息 正文
消息 发送 正文
单向 散列
消息 摘要
//形成RSA密钥对 KeyPairGenerator keyGen=KeyPairGenerator.getInstance("RSA"); keyGen.initialize(1024); //生成公钥和私钥对 KeyPair key=keyGen.generateKeyPair();
//实例化Signature,用于产生数字签名,指定用RSA和SHA算法 Signature sig=Signature.getInstance("SHA1WithRSA"); //得到私钥 PrivateKey privateKey = key.getPrivate(); //用私钥来初始化数字签名对象 sig.initSign(privateKey); //对msgBytes实施签名 sig.update(msgBytes); //完成签名,将结果放入字节数组signatureBytes
public byte[] getSignature(String msg) throws InvalidKeyException,SignatureException
相关文档
最新文档