用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验签的方法。

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

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

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

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

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

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

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

四、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编码

使⽤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中的实现

网络安全技术应用——数字签名技术在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点名签到功能实现方法在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`的表,其中包含学生的姓名和是否已经签到的信息。

【Java密码学】使用BouncyCastle生成数字签名、数字信封

【Java密码学】使用BouncyCastle生成数字签名、数字信封

【Java密码学】使⽤BouncyCastle⽣成数字签名、数字信封Bouncy Castle(轻量级密码术包)是⼀种⽤于平台的开放源码的轻量级密码术包,它⽀持⼤量的密码术,并提供 JCE 1.2.1 的实现。

最近项⽬上正好⽤到了Bouncy Castle,⽤于⽣成数字签名、数字信封,去⽹上找了很久,都没有找到合适的案例,⽽Bouncy Castle本⾝的⽂档也不多,最有⽤的就是官⽹上的Java Doc⽂档,因为这个问题也困扰了我好⼏天,最后还是通过阅读Java Doc⽂档找到了合适的类和⽅法,果然阅读Doc⽂档还是很有必要的啊。

好了,话不多说,把我写的⽅法列出来,以防忘记,并给有同样需求的同学提供⼀些参考,其中有些代码也是参考了⽹上的写法,最有⽤的还是Doc⽂档⾥提供的⼀些⽰例写法,基本的需求已经能够满⾜了。

要使⽤Bouncy Castle,就需要引⼊相应的jar包,在官⽹就可以根据⾃⼰的需要进⾏下载,然后就可以使⽤了。

import java.io.FileInputStream;import java.io.InputStream;import java.security.KeyStore;import java.security.PrivateKey;import java.security.Provider;import java.security.Security;import java.security.cert.Certificate;import java.security.cert.CertificateFactory;import java.security.cert.X509Certificate;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import java.util.List;import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;import org.bouncycastle.cert.X509CertificateHolder;import org.bouncycastle.cert.jcajce.JcaCertStore;import org.bouncycastle.cms.CMSEnvelopedData;import org.bouncycastle.cms.CMSEnvelopedDataGenerator;import org.bouncycastle.cms.CMSProcessableByteArray;import org.bouncycastle.cms.CMSSignedData;import org.bouncycastle.cms.CMSSignedDataGenerator;import org.bouncycastle.cms.CMSTypedData;import org.bouncycastle.cms.RecipientInformation;import org.bouncycastle.cms.RecipientInformationStore;import org.bouncycastle.cms.SignerInformation;import org.bouncycastle.cms.SignerInformationStore;import org.bouncycastle.cms.jcajce.JcaSignerInfoGeneratorBuilder;import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;import org.bouncycastle.jce.provider.BouncyCastleProvider;import org.bouncycastle.operator.ContentSigner;import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;import org.bouncycastle.util.Store;import org.bouncycastle.util.encoders.Base64;public class MessageUtil {private String ksType = "PKCS12";/*** ⽣成数字签名* @param srcMsg 源信息* @param charSet 字符编码* @param certPath 证书路径* @param certPwd 证书密码* @return*/public byte[] signMessage(String srcMsg, String charSet, String certPath, String certPwd) {String priKeyName = null;char passphrase[] = certPwd.toCharArray();try {Provider provider = new BouncyCastleProvider();// 添加BouncyCastle作为安全提供Security.addProvider(provider);// 加载证书KeyStore ks = KeyStore.getInstance(ksType);ks.load(new FileInputStream(certPath), passphrase);if (ks.aliases().hasMoreElements()) {priKeyName = ks.aliases().nextElement();}Certificate cert = (Certificate) ks.getCertificate(priKeyName);// 获取私钥PrivateKey prikey = (PrivateKey) ks.getKey(priKeyName, passphrase);X509Certificate cerx509 = (X509Certificate) cert;List<Certificate> certList = new ArrayList<Certificate>();certList.add(cerx509);CMSTypedData msg = (CMSTypedData) new CMSProcessableByteArray(srcMsg.getBytes(charSet));Store certs = new JcaCertStore(certList);CMSSignedDataGenerator gen = new CMSSignedDataGenerator();ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA").setProvider("BC").build(prikey);gen.addSignerInfoGenerator(new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()).build(sha1Signer, cerx509));gen.addCertificates(certs);CMSSignedData sigData = gen.generate(msg, true);return Base64.encode(sigData.getEncoded());} catch (Exception e) {e.printStackTrace();return null;}}/*** 验证数字签名* @param signedData* @return*/public boolean signedDataVerify(byte[] signedData) {boolean verifyRet = true;try {// 新建PKCS#7签名数据处理对象CMSSignedData sign = new CMSSignedData(signedData);// 添加BouncyCastle作为安全提供Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());// 获得证书信息Store certs = sign.getCertificates();// 获得签名者信息SignerInformationStore signers = sign.getSignerInfos();Collection c = signers.getSigners();Iterator it = c.iterator();// 当有多个签名者信息时需要全部验证while (it.hasNext()) {SignerInformation signer = (SignerInformation) it.next();// 证书链Collection certCollection = certs.getMatches(signer.getSID());Iterator certIt = certCollection.iterator();X509CertificateHolder cert = (X509CertificateHolder) certIt.next();// 验证数字签名if (signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))) {verifyRet = true;} else {verifyRet = false;}}} catch (Exception e) {verifyRet = false;e.printStackTrace();System.out.println("验证数字签名失败");}return verifyRet;}/*** 加密数据* @param srcMsg 源信息* @param certPath 证书路径* @param charSet 字符编码* @return* @throws Exception*/public String envelopeMessage(String srcMsg, String certPath, String charSet) throws Exception {CertificateFactory certificatefactory;X509Certificate cert;// 使⽤公钥对对称密钥进⾏加密 //若此处不加参数 "BC" 会报异常:CertificateException -certificatefactory = CertificateFactory.getInstance("X.509", "BC");// 读取.crt⽂件;你可以读取绝对路径⽂件下的crt,返回⼀个InputStream(或其⼦类)即可。

JavaPDF添加数字签名的实现方法

JavaPDF添加数字签名的实现方法

JavaPDF添加数字签名的实现⽅法经过数字签名的⽂档,能够使作者之外的⼈⽆法对其进⾏修改。

因此,在PDF⽂档中添加数字签名可以保证其安全性和真实性。

同时根据添加内容的差异性,数字签名可分为⽂本数字签名、图⽚数字签名、图⽚及⽂本数字签名。

本⽂将通过Spire.PDF for Java来演⽰如何在PDF⽂档中添加数字签名。

使⽤⼯具:Jar⽂件获取及导⼊:⽅法1:通过获取Jar包。

下载后,解压⽂件,并将lib⽂件夹下的Spire.Pdf.jar⽂件导⼊Java程序。

(如下图)⽅法2:通过maven仓库安装导⼊。

具体安装教程详见此⽹页。

⽰例1:添加⽂本数字签名import com.spire.pdf.PdfDocument;import com.spire.pdf.graphics.PdfTrueTypeFont;import com.spire.pdf.security.GraphicMode;import com.spire.pdf.security.PdfCertificate;import com.spire.pdf.security.PdfCertificationFlags;import com.spire.pdf.security.PdfSignature;import java.awt.*;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;public class TextSignature {public static void main(String[] args) {//加载PDF⽂档PdfDocument doc = new PdfDocument();doc.loadFromFile("C:\\Users\\Test1\\Desktop\\Sample.pdf");//加载pfx证书PdfCertificate cert = new PdfCertificate("C:\\Users\\Test1\\Desktop\\gary.pfx", "abc123");//添加数字签名,设置其位置和⼤⼩PdfSignature signature = new PdfSignature(doc, doc.getPages().get(doc.getPages().getCount()-1), cert, "MySignature");Rectangle2D rect = new Rectangle2D.Float();rect.setFrame(new Point2D.Float((float) doc.getPages().get(0).getActualSize().getWidth() - 270, (float) doc.getPages().get(0).getActualSize().getHeight() - 300), new Dimension(200, 110)); signature.setBounds(rect);//设置签名为⽂本形式signature.setGraphicMode(GraphicMode.Sign_Detail);//设置签名的内容signature.setNameLabel("签字者:");signature.setName("Gary");signature.setContactInfoLabel("联系电话:");signature.setContactInfo("010333555");signature.setDateLabel("⽇期:");signature.setDate(new java.util.Date());signature.setLocationInfoLabel("地点:");signature.setLocationInfo("US");signature.setReasonLabel("原因:");signature.setReason("我是⽂档所有者");signature.setDistinguishedNameLabel("DN: ");signature.setDistinguishedName(signature.getCertificate().get_IssuerName().getName());//设置签名的字体signature.setSignDetailsFont(new PdfTrueTypeFont(new Font("Arial Unicode MS", Font.PLAIN, 11)));//设置⽂档权限为禁⽌更改signature.setDocumentPermissions(PdfCertificationFlags.Forbid_Changes);signature.setCertificated(true);//保存⽂档doc.saveToFile("output/TextSignature.pdf");doc.close();}}⽂本数字签名效果:⽰例2:添加图⽚数字签名import com.spire.pdf.PdfDocument;import com.spire.pdf.graphics.PdfImage;import com.spire.pdf.graphics.PdfTrueTypeFont;import com.spire.pdf.security.GraphicMode;import com.spire.pdf.security.PdfCertificate;import com.spire.pdf.security.PdfCertificationFlags;import com.spire.pdf.security.PdfSignature;import java.awt.*;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;public class ImageSignature {public static void main(String[] args) {//加载PDF⽂档PdfDocument doc = new PdfDocument();doc.loadFromFile("C:\\Users\\Test1\\Desktop\\Sample.pdf");//加载pfx证书PdfCertificate cert = new PdfCertificate("C:\\Users\\Test1\\Desktop\\gary.pfx", "abc123");//添加数字签名,设置其位置和⼤⼩PdfSignature signature = new PdfSignature(doc, doc.getPages().get(doc.getPages().getCount()-1), cert, "MySignature");Rectangle2D rect = new Rectangle2D.Float();rect.setFrame(new Point2D.Float((float) doc.getPages().get(0).getActualSize().getWidth() - 250, (float) doc.getPages().get(0).getActualSize().getHeight() - 300), new Dimension(170, 150)); signature.setBounds(rect);//设置签名为图⽚形式signature.setGraphicMode(GraphicMode.Sign_Image_Only);signature.setSignImageSource(PdfImage.fromFile("C:\\Users\\Test1\\Desktop\\Image.png"));//设置签名的字体signature.setSignDetailsFont(new PdfTrueTypeFont(new Font("Arial Unicode MS", Font.PLAIN, 11)));//设置⽂档权限为禁⽌更改signature.setDocumentPermissions(PdfCertificationFlags.Forbid_Changes);signature.setCertificated(true);//保存⽂档doc.saveToFile("output/ImageSignature.pdf");doc.close();}}图⽚数字签名效果:⽰例3:添加图⽚及⽂本数字签名import com.spire.pdf.PdfDocument;import com.spire.pdf.graphics.*;import com.spire.pdf.security.GraphicMode;import com.spire.pdf.security.PdfCertificate;import com.spire.pdf.security.PdfCertificationFlags;import com.spire.pdf.security.PdfSignature;import java.awt.*;import java.awt.geom.Point2D;import java.awt.geom.Rectangle2D;public class TextAndImageSignature {public static void main(String[] args) {//加载PDF⽂档PdfDocument doc = new PdfDocument();doc.loadFromFile("C:\\Users\\Test1\\Desktop\\Sample.pdf");//加载pfx证书PdfCertificate cert = new PdfCertificate("C:\\Users\\Test1\\Desktop\\gary.pfx", "abc123");//添加数字签名,设置其位置和⼤⼩PdfSignature signature = new PdfSignature(doc, doc.getPages().get(doc.getPages().getCount()-1), cert, "MySignature");Rectangle2D rect = new Rectangle2D.Float();rect.setFrame(new Point2D.Float((float) doc.getPages().get(0).getActualSize().getWidth() - 350, (float) doc.getPages().get(0).getActualSize().getHeight() - 170), new Dimension(300, 170)); signature.setBounds(rect);//设置签名为图⽚加⽂本模式signature.setGraphicMode(GraphicMode.Sign_Image_And_Sign_Detail);//设置签名的内容signature.setNameLabel("签字者:");signature.setName("Gary");signature.setContactInfoLabel("联系电话:");signature.setContactInfo("010333555");signature.setDateLabel("⽇期:");signature.setDate(new java.util.Date());signature.setLocationInfoLabel("地点:");signature.setLocationInfo("US");signature.setReasonLabel("原因:");signature.setReason("我是⽂档所有者");signature.setDistinguishedNameLabel("DN: ");signature.setDistinguishedName(signature.getCertificate().get_IssuerName().getName());signature.setSignImageSource(PdfImage.fromFile("C:\\Users\\Test1\\Desktop\\Image.png"));//设置签名的字体 signature.setSignDetailsFont(new PdfTrueTypeFont(new Font("Arial Unicode MS", Font.PLAIN, 11)));//设置⽂档权限为禁⽌更改signature.setDocumentPermissions(PdfCertificationFlags.Forbid_Changes);signature.setCertificated(true);//保存⽂档doc.saveToFile("output/TextAndImageSignature.pdf");doc.close();}}图⽚及⽂本数字签名效果:以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

jdk 签名函数

jdk 签名函数

jdk 签名函数JDK(Java Development Kit)提供了许多用于数字签名的类和方法。

以下是使用Java 的JDK签名功能的一般步骤:1.创建签名对象:使用Signature类创建一个签名对象。

可以使用getInstance()方法获取特定算法的实例,例如SHA256withRSA。

java复制代码Signature signature = Signature.getInstance("SHA256withRSA");2.初始化签名对象:使用initSign()方法初始化签名对象,并使用私钥对数据进行签名。

在此步骤中,需要将私钥传递给initSign()方法。

java复制代码PrivateKey privateKey = getPrivateKey(); // 获取私钥signature.initSign(privateKey);3.更新要签名的数据:使用update()方法将要签名的数据传递给签名对象。

可以多次调用此方法来添加更多数据。

java复制代码byte[] data = "要签名的数据".getBytes();signature.update(data);4.完成签名:使用sign()方法完成签名并生成签名结果。

java复制代码byte[] signatureBytes = signature.sign();5.验证签名:使用verify()方法验证签名。

在此步骤中,需要将公钥传递给verify()方法,以及要验证签名的数据和签名本身。

java复制代码PublicKey publicKey = getPublicKey(); // 获取公钥byte[] data = "要验证签名的数据".getBytes();byte[] signatureToVerify = getSignatureToVerify(); // 获取要验证的签名boolean isValid = signature.verify(signatureToVerify, data);这些是使用JDK进行数字签名的基本步骤。

java hmacsha256 签名转原文

java hmacsha256 签名转原文

一、基本概念Java HMACSHA256签名是一种常用的加密算法,它可以对数据进行签名并进行验证,从而确保数据的完整性和安全性。

HMAC是“Hash-based Message Authentication Code”的缩写,SHA256是一种安全哈希算法,两者结合在一起可以用于生成数字签名。

二、算法原理HMACSHA256签名的原理是将原始数据通过SHA256算法进行哈希运算,然后使用一个密钥对哈希结果进行加密,最后生成签名。

在验证时,接收方可以通过相同的密钥和原始数据重新计算签名,然后与接收到的签名进行比对,从而判断数据的完整性和真实性。

三、Java实现在Java中,我们可以通过javax.crypto包中的相关类来实现HMACSHA256签名。

下面给出一个简单的示例代码:```javaimport javax.crypto.Mac;import javax.crypto.spec.SecretKeySpec;public class HMACSHA256 {public static String sign(String data, String key) {try {Mac sha256_HMAC = Mac.getInstance("HmacSHA256"); SecretKeySpec secret_key = newSecretKeySpec(key.getBytes(), "HmacSHA256");sha256_HMAC.init(secret_key);byte[] hash = sha256_HMAC.doFinal(data.getBytes()); return bytesToHex(hash);} catch (Exception e) {e.printStackTrace();return null;}}private static String bytesToHex(byte[] bytes) {StringBuilder result = new StringBuilder();for (byte b : bytes) {result.append(String.format("02x", b));}return result.toString();}}```四、调用示例使用上面的HMACSHA256类进行签名和验证很简单,下面是一个调用示例:```javapublic class M本人n {public static void m本人n(String[] args) {String data = "Hello, world!";String key = "mySecretKey";String signature = HMACSHA256.sign(data, key);System.out.println("Signature: " + signature);// 验证签名String newData = "Hello, world!";String newSignature = HMACSHA256.sign(newData, key); if (signature.equals(newSignature)) {System.out.println("Signature verified!");} else {System.out.println("Signature verification f本人led!"); }}}```五、安全性考虑在使用HMACSHA256签名时,需要注意以下几点以确保数据的安全性:1. 密钥的安全性:密钥是签名的关键,必须严格保管,避免泄露。

java 加签方法 -回复

java 加签方法 -回复

java 加签方法-回复Java加签方法,指的是在Java编程中进行数字签名的过程。

数字签名是在互联网通信中保证数据完整性、真实性和不可否认性的重要手段之一。

在网络传输中,数据可能会被篡改、伪造或篡改。

数字签名通过私钥对数据进行加密,然后通过公钥对加密后的数据进行解密和验证,以确保数据的完整性和真实性。

下面,我们将一步一步回答有关Java加签方法的问题。

1. 什么是数字签名?数字签名是将数据进行加密后,用私钥对加密后的数据进行签名,以确保数据在传输过程中的完整性、真实性和不可否认性。

数字签名可以用于验证数据的来源和完整性,防止数据被篡改或伪造。

2. 如何进行数字签名?在Java编程中,可以使用Java提供的密钥对生成器和数字签名算法来进行数字签名。

首先,需要生成一对密钥,包括公钥和私钥。

公钥用于对数据进行加密,私钥用于对加密后的数据进行解密和验证。

然后,使用私钥对数据进行加密并生成数字签名,将数据和数字签名一起传输。

接收方可以使用公钥对收到的数据进行解密和验证,以确保数据的完整性和真实性。

3. 如何在Java中生成密钥对?在Java中,可以使用Java密钥对生成器类(KeyPairGenerator)来生成密钥对。

首先,需要选择一个合适的算法,例如RSA或DSA。

然后,使用密钥对生成器类初始化并生成密钥对。

最后,可以使用公钥和私钥进行数字签名和验证操作。

4. 如何进行数字签名?在Java中,可以使用Java数字签名类(Signature)来进行数字签名。

首先,需要选择一个合适的数字签名算法,例如SHA1withRSA或SHA256withDSA。

然后,使用私钥初始化数字签名对象。

接着,使用update方法更新要签名的数据,可以多次调用update方法传入数据的不同部分。

最后,使用sign方法对数据进行签名,生成数字签名。

5. 如何验证数字签名?在Java中,可以使用Java数字签名类(Signature)来验证数字签名。

javaSHA1WithRSA算法

javaSHA1WithRSA算法

javaSHA1WithRSA算法SHA1WithRSA是一种经典的数字签名算法,利用SHA1摘要算法和RSA非对称加密算法结合起来实现数字签名,保证数据的完整性和安全性。

下面将对该算法进行详细介绍和解析。

1.算法原理首先,SHA1WithRSA算法使用SHA1(Secure Hash Algorithm 1)算法对原始数据进行摘要计算,得到一个固定长度的摘要值,通常为160位(20字节),这个摘要值可以唯一的代表原始数据。

接下来,使用RSA加密算法对摘要值进行加密,生成一个数字签名。

RSA是一种非对称加密算法,使用公钥进行加密,使用私钥进行解密。

对于SHA1WithRSA算法而言,签名的过程是使用私钥对摘要值进行加密,生成签名;而验证的过程则是使用公钥对签名进行解密,还原原始的摘要值。

最后,接收到数字签名的一方,可以根据原始数据、公钥和数字签名,验证数字签名的真实性。

具体过程是首先使用相同的SHA1算法对原始数据进行摘要计算,得到一个新的摘要值,然后使用发送方的公钥对数字签名进行解密,还原原始的摘要值,并与新计算得到的摘要值进行比对,如果两个摘要值相同,则说明数字签名没有被篡改,数据可信。

2.实现过程实现SHA1WithRSA算法的关键是对原始数据进行摘要计算和RSA非对称加密。

2.1摘要计算摘要计算使用SHA1算法,将原始数据转化为一个固定长度的摘要值。

Java提供了MessageDigest类来实现SHA1算法的摘要计算。

```javaString originalData = "Hello, world!";MessageDigest sha1Digest = MessageDigest.getInstance("SHA1");byte[] sha1Hash = sha1Digest.digest(originalData.getBytes();```2.2RSA加密和解密RSA非对称加密算法使用公钥对数据进行加密,使用私钥对加密的数据进行解密。

Java代码实现文件添加数字签名、验证数字签名

Java代码实现文件添加数字签名、验证数字签名

Java代码实现⽂件添加数字签名、验证数字签名Linux下实现加签、验签1.使⽤OpenSSL ⽣成公钥和密钥;#⽤ OpenSSL, Linux 上⾃带,常⽤命令如下:#⽣成 RSA 私钥(传统格式的)openssl genrsa -out rsa_private_key.pem 1024#将传统格式的私钥转换成 PKCS#8 格式的(JAVA需要使⽤的私钥需要经过PKCS#8编码,PHP程序不需要,可以直接略过)openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt#⽣成 RSA 公钥openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem2.使⽤私钥对⽂件进⾏加签、并验证#有明⽂⽂件file.txt和RSA密钥rsa_private_key.pem#使⽤md5指令指定sha1算法,对file.txt进⾏签名,⽣成签名⽂件sign1.txtopenssl md5 -sha512 -sign rsa_private_key.pem -out data_xinbao.tar.gz.sign data_xinbao.tar.gz#使⽤md5指令指定sha1算法,对file.txt进⾏签名,⽣成签名⽂件sign1.txtopenssl dgst -sha512 -sign rsa_private_key.pem -out data_xinbao.tar.gz.sign data_xinbao.tar.gz#两个签名⽂件⼀样,说明两个指令完成相同的功能diff data_xinbao.tar.gz.sign data_xinbao1.tar.gz.sign#使⽤RSA公钥验证签名(verify参数),验证成功openssl md5 -verify rsa_public_key.pem -sha512 -signature data_xinbao1.tar.gz.sign data_xinbao.tar.gzopenssl dgst -verify rsa_public_key.pem -sha512 -signature data_xinbao.tar.gz.sign data_xinbao.tar.gz3.查看OpenSSL和帮助#通过下⾯命令可以查看openssl的参数说明$ openssl dgst -options are-c to output the digest with separating colons-r to output the digest in coreutils format-d to output debug info-hex output as hex dump-binary output in binary form-sign file sign digest using private key in file-verify file verify a signature using public key in file-prverify file verify a signature using private key in file-keyform arg key file format (PEM or ENGINE)-out filename output to filename rather than stdout-signature file signature to verify-sigopt nm:v signature parameter-hmac key create hashed MAC with key-mac algorithm create MAC (not neccessarily HMAC)-macopt nm:v MAC algorithm parameters or key-engine e use engine e, possibly a hardware device.-md4 to use the md4 message digest algorithm-md5 to use the md5 message digest algorithm-ripemd160 to use the ripemd160 message digest algorithm-sha to use the sha message digest algorithm-sha1 to use the sha1 message digest algorithm-sha224 to use the sha224 message digest algorithm-sha256 to use the sha256 message digest algorithm-sha384 to use the sha384 message digest algorithm-sha512 to use the sha512 message digest algorithm-whirlpool to use the whirlpool message digest algorithm4.拿加签的原⽂件和加签后的⽂件使⽤Java代码进⾏对⽐;import javax.crypto.BadPaddingException;import javax.crypto.Cipher;import javax.crypto.IllegalBlockSizeException;import javax.crypto.NoSuchPaddingException;import java.io.*;import java.security.*;import java.security.interfaces.RSAPrivateKey;import java.security.interfaces.RSAPublicKey;import java.security.spec.InvalidKeySpecException;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.Date;/*** 对⽂件加签、验签⼯具类* ⽣成私钥:openssl genrsa -out rsa_private_key.pem 1024* 私钥还不能直接被使⽤,需要进⾏PKCS#8编码:openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt* 根据私钥⽣成公钥:openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem* 使⽤私钥sha512签名:openssl dgst -sha512 -sign rsa_private_key.pem -out xx.tar.gz.sign xx.tar.gz* 使⽤公钥sha512验签:openssl dgst -verify rsa_public_key.pem -sha512 -signature xx.tar.gz.sign xx.tar.gz* @author XIHONGLIE* @date 2018-03-27*/public class RsaEncrypt {/*** rsa签名* @param data 待签名的字符串* @param priKey rsa私钥字符串* @return签名结果* @throws Exception 签名失败则抛出异常*/public byte[] rsaSign(byte[] data, RSAPrivateKey priKey)throws SignatureException {try {Signature signature = Signature.getInstance("SHA512withRSA");signature.initSign(priKey);signature.update(data);byte[] signed = signature.sign();return signed;} catch (Exception e) {throw new SignatureException("RSAcontent = " + data+ "; charset = ", e);}}/*** rsa验签* @param data 被签名的内容* @param sign 签名后的结果* @param pubKey rsa公钥* @return验签结果* @throws SignatureException 验签失败,则抛异常*/public boolean verify(byte[] data, byte[] sign, RSAPublicKey pubKey)throws SignatureException {try {Signature signature = Signature.getInstance("SHA512withRSA");signature.initVerify(pubKey);signature.update(data);return signature.verify(sign);} catch (Exception e) {e.printStackTrace();throw new SignatureException("RSA验证签名[content = " + data+ "; charset = " + "; signature = " + sign + "]发⽣异常!", e);}}/*** 私钥*/private RSAPrivateKey privateKey;/*** 公钥*/private RSAPublicKey publicKey;/*** 字节数据转字符串专⽤集合*/private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6','7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };/*** 获取私钥* @return当前的私钥对象*/public RSAPrivateKey getPrivateKey() {return privateKey;}/*** 获取公钥* @return当前的公钥对象*/public RSAPublicKey getPublicKey() {return publicKey;}/*** 随机⽣成密钥对*/public void genKeyPair() {KeyPairGenerator keyPairGen = null;try {keyPairGen = KeyPairGenerator.getInstance("RSA");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}keyPairGen.initialize(1024, new SecureRandom());KeyPair keyPair = keyPairGen.generateKeyPair();this.privateKey = (RSAPrivateKey) keyPair.getPrivate();this.publicKey = (RSAPublicKey) keyPair.getPublic();}/*** 从.pem⽂件中取得私钥* @param filePath ⽂件路径* @return私钥*/public String getPrivateKeyFromFile(String filePath){String strPrivateKey = "";try {BufferedReader privateKey = new BufferedReader(new FileReader(filePath));String line = "";while((line = privateKey.readLine()) != null){strPrivateKey += line;}privateKey.close();strPrivateKey = strPrivateKey.replace("-----BEGIN PRIVATE KEY-----","").replace("-----END PRIVATE KEY-----",""); }catch (Exception e){e.printStackTrace();}return strPrivateKey;}/*** 从.pem⽂件中取得公钥* @param filePath ⽂件路径* @return公钥*/public String getPublicKeyFromFile(String filePath){String strPublicKey = "";try {BufferedReader publicKey = new BufferedReader(new FileReader(filePath));String line = "";while((line = publicKey.readLine()) != null){strPublicKey += line;}publicKey.close();strPublicKey = strPublicKey.replace("-----BEGIN PUBLIC KEY-----","").replace("-----END PUBLIC KEY-----","");}catch (Exception e){e.printStackTrace();}return strPublicKey;}/*** 从字符串中加载公钥* @param publicKeyStr 公钥数据字符串* @throws Exception 加载公钥时产⽣的异常*/public void loadPublicKey(String publicKeyStr) throws Exception {try {byte[] buffer = Base64Utils.decode(publicKeyStr);KeyFactory keyFactory = KeyFactory.getInstance("RSA");X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);this.publicKey = (RSAPublicKey) keyFactory.generatePublic(keySpec);} catch (NoSuchAlgorithmException e) {throw new Exception("⽆此算法");} catch (InvalidKeySpecException e) {throw new Exception("公钥⾮法");}catch (NullPointerException e) {throw new Exception("公钥数据为空");}}/*** 加载私钥* @param privateKeyStr 私钥⽂件名* @return是否成功* @throws Exception*/public void loadPrivateKey(String privateKeyStr) throws Exception {try {byte[] buffer = Base64Utils.decode(privateKeyStr);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer); KeyFactory keyFactory = KeyFactory.getInstance("RSA");this.privateKey = (RSAPrivateKey) keyFactory.generatePrivate(keySpec); } catch (NoSuchAlgorithmException e) {throw new Exception("⽆此算法");} catch (InvalidKeySpecException e) {throw new Exception("私钥⾮法");} catch (NullPointerException e) {throw new Exception("私钥数据为空");}}/*** 加密过程* @param publicKey 公钥* @param plainTextData 明⽂数据* @return* @throws Exception 加密过程中的异常信息*/public byte[] encrypt(RSAPublicKey publicKey, byte[] plainTextData) throws Exception {if (publicKey == null) {throw new Exception("加密公钥为空, 请设置");}Cipher cipher = null;try {cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);byte[] output = cipher.doFinal(plainTextData);return output;} catch (NoSuchAlgorithmException e) {throw new Exception("⽆此加密算法");} catch (NoSuchPaddingException e) {e.printStackTrace();return null;} catch (InvalidKeyException e) {throw new Exception("加密公钥⾮法,请检查");} catch (IllegalBlockSizeException e) {throw new Exception("明⽂长度⾮法");} catch (BadPaddingException e) {throw new Exception("明⽂数据已损坏");}}/*** 解密过程* @param privateKey 私钥* @param cipherData 密⽂数据* @return明⽂* @throws Exception 解密过程中的异常信息*/public byte[] decrypt(RSAPrivateKey privateKey, byte[] cipherData)throws Exception {if (privateKey == null) {throw new Exception("解密私钥为空, 请设置");}Cipher cipher = null;try {cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] output = cipher.doFinal(cipherData);return output;} catch (NoSuchAlgorithmException e) {throw new Exception("⽆此解密算法");} catch (NoSuchPaddingException e) {e.printStackTrace();return null;} catch (InvalidKeyException e) {throw new Exception("解密私钥⾮法,请检查");} catch (IllegalBlockSizeException e) {throw new Exception("密⽂长度⾮法");} catch (BadPaddingException e) {throw new Exception("密⽂数据已损坏");}}/*** 字节数据转⼗六进制字符串* @param data 输⼊数据* @return⼗六进制内容*/public static String byteArrayToString(byte[] data) {StringBuilder stringBuilder = new StringBuilder();for (int i = 0; i < data.length; i++) {// 取出字节的⾼四位作为索引得到相应的⼗六进制标识符注意⽆符号右移 stringBuilder.append(HEX_CHAR[(data[i] & 0xf0) >>> 4]);// 取出字节的低四位作为索引得到相应的⼗六进制标识符stringBuilder.append(HEX_CHAR[(data[i] & 0x0f)]);if (i < data.length - 1) {stringBuilder.append(' ');}}return stringBuilder.toString();}/*** btye转换hex函数* @param byteArray* @return*/public static String byteToHex(byte[] byteArray) {StringBuffer strBuff = new StringBuffer();for (int i = 0; i < byteArray.length; i++) {if (Integer.toHexString(0xFF & byteArray[i]).length() == 1) {strBuff.append("0").append(Integer.toHexString(0xFF & byteArray[i]));} else {strBuff.append(Integer.toHexString(0xFF & byteArray[i]));}}return strBuff.toString();}/*** 以字节为单位读取⽂件,常⽤于读⼆进制⽂件,如图⽚、声⾳、影像等⽂件。

java中p7签名值获取算法类型

java中p7签名值获取算法类型

在Java中,P7签名值通常用于身份验证和加密算法中。

P7签名值是根据特定的算法生成的,通常用于验证用户身份和数据完整性。

在Java中,P7签名值的获取算法通常采用以下几种类型:
1. RSA算法:RSA算法是一种常用的公钥加密算法,它使用两个密钥:公钥和私钥。

在P7签名值生成过程中,通常使用公钥进行加密,私钥进行解密。

通过使用RSA算法,可以生成具有特定格式的P7签名值,用于验证用户身份和数据完整性。

2. SHA-256算法:SHA-256算法是一种常用的哈希算法,它可以将任意长度的数据转换为固定长度的哈希值。

在P7签名值生成过程中,通常使用SHA-256算法对数据进行哈希处理,生成具有特定格式的P7签名值。

3. HMAC算法:HMAC算法是一种基于密钥的消息认证码算法,它使用密钥和消息生成一个唯一的哈希值。

在P7签名值生成过程中,通常使用HMAC算法对数据进行签名,生成具有特定格式的P7签名值。

以上三种算法是Java中常见的P7签名值获取算法类型。

每种算法都有其独特的特性和优势,可以根据具体的应用场景选择合适的算法类型。

在获取P7签名值时,通常需要使用相应的加密库或工具来实现。

总之,Java中P7签名值的获取算法类型取决于具体的应用场景和需求,可以选择合适的算法类型来实现P7签名值的生成和验证。

java中character.isletterordigit的用法

java中character.isletterordigit的用法

Java中的Character.isLetterOrDigit方法的用法详解在Java编程语言中,Character类提供了一系列的方法用于处理字符数据。

其中,isLetterOrDigit方法是一个非常实用的方法,它可以用来判断一个字符是否为字母或数字。

本文将详细介绍这个方法的用法。

一、方法签名首先,我们来看一下Character.isLetterOrDigit方法的签名:```javapublic static boolean isLetterOrDigit(char ch)```这个方法接受一个char类型的参数,如果该字符是字母或数字,则返回true,否则返回false。

二、方法功能顾名思义,isLetterOrDigit方法的主要功能就是判断一个字符是否为字母或数字。

这里的字母包括大写字母和小写字母,数字则包括0-9这10个数字。

三、使用示例下面是一些使用isLetterOrDigit方法的示例:1. 判断一个字符是否为字母或数字```javachar ch = 'A';boolean result = Character.isLetterOrDigit(ch);System.out.println(result); // 输出:true```在这个例子中,字符'A'是一个大写字母,因此isLetterOrDigit方法返回true。

2. 遍历字符串并判断每个字符是否为字母或数字```javaString str = "Hello, World!";for (char ch : str.toCharArray()) {if (Character.isLetterOrDigit(ch)) {System.out.print(ch + " ");}}```在这个例子中,我们遍历了字符串"Hello, World!"中的每个字符,对于每一个字符,我们都调用了isLetterOrDigit方法进行判断。

  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
相关文档
最新文档