RSA签名算法 - Java加密与安全
RSA签名算法在非对称加密中我们可以看到,甲乙双方要进行通信,用publicKey进行加密,用priavteKey解密,这个时候会出现一个问题,如果黑客用你的publicKey对消息进行加密,然后冒充甲发送给乙,乙怎么确定这个消息是甲发送,还是有人伪造甲发送的呢,所以我们就需要数字签证算法,发送加密消息的时候同时需要发送签名,而这个签名是需要甲的privateKey计算的,而乙要验证这个签名,是否是合法的,它会用甲的publicKey进行验证,如果验证成功,证明这个消息确实是甲发送的
数字签名就是发送方用自己的私钥对消息进行签名,然后接受方用发送方的私钥来验证签名是否有效,我们可以把数字签名混入了公钥和私钥的一种摘要,publicKey和原始签名和message着三个中的任何一个被修改了,签名都是无效的数字签名的目的是:1. 确认信息是某个发送方发送的,因为只有他用自己的privateKey签名,其他人才能用它的publicKey去验证这个签名2. 发送方还不能抵赖他发送了消息,因为用谁的publicKey成功验证的签名,就一定是谁用privateKey签名的,所以privateKey就相当于用户的身份3. 最后数字签名保证在传输过程中没有被修改常用的数字签名算法有:1. MD5WithRSA2. SHA1WithRSA3. SHA256WithRSA
package com.learn.securl;import java.security.GeneralSecurityException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;/*** 使用RSA签名算法的时候* 我们同样要生成privateKey和publicKey* @author Leon.Sun**/
public class SecRSASignature {PrivateKey sk;PublicKey pk;/*** 生成公钥/私钥对* @throws GeneralSecurityException*/public SecRSASignature() throws GeneralSecurityException{/*** 生成KeyPair的方法和使用RSA加密是一样的*/KeyPairGenerator kpGen = KeyPairGenerator.getInstance("RSA");kpGen.initialize(1024);KeyPair kp = kpGen.generateKeyPair();this.sk = kp.getPrivate();this.pk = kp.getPublic();}/*** 从以保存的字节中(例如:读取文件)恢复公钥/私钥* @param pk* @param sk* @throws GeneralSecurityException*/public SecRSASignature(byte[] pk, byte[] sk) throws GeneralSecurityException{KeyFactory kf = KeyFactory.getInstance("RSA");X509EncodedKeySpec pkSpec = new X509EncodedKeySpec(pk);this.pk = kf.generatePublic(pkSpec);PKCS8EncodedKeySpec skSpec = new PKCS8EncodedKeySpec(sk);this.sk = kf.generatePrivate(skSpec);}/*** 把私钥导出为字节* @return*/public byte[] getProvateKey(){return this.sk.getEncoded();}/*** 把公钥导出为字节* @return*/public byte[] getPublicKey(){return this.pk.getEncoded();}/*** sign by sk* 然后我们定义一个sign方法* 用于对数据进行签名* 当我们使用签名算法的时候* @param message* @return* @throws GeneralSecurityException*/public byte[] sign(byte[] message) throws GeneralSecurityException{/*** 我们首先通过Signature.getInstance* 然后传入签名算法的算法名称* 这里我们使用SHA1withRSA* 我们就得到一个Signature对象*/Signature signature = Signature.getInstance("SHA1withRSA");/*** 然后我们调用initSign* 传入我们的privateKey* 初始化一个签名*/signature.initSign(this.sk);/*** 紧接着我们用update方法传入一个消息* 表示这个消息进行签名*/signature.update(message);/*** 接着我们用signature的sign方法* 就可以获得签名以后的字节*/return signature.sign();}/*** sign by pk* 我们再定义一个verify方法来验证签名* 验证签名的时候* 我们需要传入原始信息和签名信息* @param message* @param sign* @return* @throws GeneralSecurityException*/public boolean verify(byte[] message, byte[] sign) throws GeneralSecurityException{/*** 同样我们调用Signature.getInstance* 然后传入SHA1withRSA* 获得一个Signature对象*/Signature signature = Signature.getInstance("SHA1withRSA");/*** 这个时候我们要调用initVerify* 然后传入publicKey* 表示我们要验证的签名* 验证签名只能使用publicKey*/signature.initVerify(this.pk);/*** 然后我们传入原始的信息*/signature.update(message);/*** 最后我们调用verigy并传入签名信息* 表示对签名进行验证* 签名的结果为true或者false*/return signature.verify(sign);}/*** 现在我们用main来对RSA签名进行测试* @param args* @throws Exception*/public static void main(String[] args) throws Exception{byte[] message = "Hello, 使用SHA1withRSA算法进行数字签名!".getBytes();SecRSASignature rsas = new SecRSASignature();/*** 我们首先通过sign方法对信息进行签名*/byte[] sign = rsas.sign(message);/*** 然后打印出签名的结果*/System.out.println("sign: " + Base64.getEncoder().encodeToString(sign));/*** 然后我们通过verify方法对信息和签名进行验证*/boolean verified = rsas.verify(message, sign);/*** 然后打印出签名的结果* * verify: true* 我们用原始的公钥进行的签名结果为true,*/System.out.println("verify: " + verified);// 用另一个公钥验证:/*** 如果我们创建另一个Signature对象* 然后用另一个公钥去验证*/boolean verified2 = new SecRSASignature().verify(message, sign);/*** 我们可以看到验证的结果为false* * verify with another public key: false* 我们用另一个publicKey进行的签名结果为false*/System.out.println("verify with another public key: " + verified2);// 修改原始信息:/*** 当我们把原始信息修改为一个字节的时候*/message[0] = 100;/*** 我们再对信息和签名进行验证* 我们可以看到改正过的信息验证的结果也应该为false* * verify changed message: false* 我们对原始信息进行的改动结果为false*/boolean verified3 = rsas.verify(message, sign);System.out.println("verify changed message: " + verified3);}
}
现在我们总结一下:1. 数字前面就是用发送方的私钥对原始数据进行签名2. 只有用发送方的公钥才能通过签名验证,这样做的目的是为了防止伪造发送方,防止抵赖发送过信息,防止发送信息发送过程中被修改3. 常用的算法有:MD5withRSA,SHA1withRSA,SHA256withRSA
RSA签名算法 - Java加密与安全相关推荐
- DSA签名算法 - Java加密与安全
DSA签名算法DSA就是Digital Signature Algorithm,他使用的是EIGamal数字签名算法DSA只能配合SHA使用:1. 所以有SHA1withDSA2. SHA256wit ...
- 第十九篇:JAVA加密解密之RSA算法
RSA算法简介 RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年首 ...
- RSA签名算法,计算调用加密报文,安全传输
RSA签名算法 1. 获取当前的时间戳参数 2. 计算参数签名 3. 获取请求对象的MD5密文 4. 通过私钥计算某个参数的RSA签名 5. 转换字符集到utf8 6. MD5加密字符串 7. bas ...
- Java 加密解密 对称加密算法 非对称加密算法 MD5 BASE64 AES RSA
[最简单的加密] 1.简单的概念 明文:加密前的信息 密文:机密后的信息 算法:加密或解密的算法 密钥:算法使用的钥匙(读作miyao,正确应该是miyue,但是大家都读miyao) 2.简单的例子 ...
- 非对称加密下RSA在Java的简明教程
引言 在现实世界中,每个人都有自己的密码.在各种系统中都有各类加密和解密的需求. 本文将详细介绍一下RSA的前身后世,应用场景和在Java中的实现,从理论到实践,一步到位,触手可用. 非对称加密与对称 ...
- Java加密技术(四)——非对称加密算法RSA
转自:http://snowolf.iteye.com/blog/381767 接下来我们介绍典型的非对称加密算法--RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能 ...
- Java进阶(七)Java加密技术之非对称加密算法RSA
Java加密技术(四)--非对称加密算法RSA 非对称加密算法--RSA 基本概念 非对称加密算法是一种密钥的保密方法. 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(priv ...
- 非对称加密——RSA算法JAVA代码实践
文章目录 说明 RSA加解密 测试代码 打印输出 说明 1:下面代码参考自<JAVA加密解密的艺术>,有部分修改,详见原理见原书 2:下面代码是RSA在JAVA中API级别的代码实现,具体 ...
- RSA node解密 java 加密的注意事项
java 代码 Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); 代替 Cipher.getInstance(&q ...
最新文章
- 查询服务器上几张显卡命令
- 西门子获首都机场18亿大单
- 腾讯与中国人民大学开源最新研究成果:3TS腾讯事务处理技术验证系统
- web.xml文件的作用
- ShadeGraph教程之节点详解1:Artistic Nodes
- Oracle学习总结(7)—— 常用的数据库索引优化语句总结
- git merge 的撤销
- 零基础学python用哪本书好-零基础想要学习Python编程 ,不知道看哪本书?
- ARM中的RO、RW和ZI DATA说明
- 下载 / 安装 Visual Studio - C语言零基础入门教程
- matlab 博弈论代码,各种博弈论详解(示例代码)
- MySQL 事务四大特性和事务隔离级别
- 科学技术法-正则表达式-QT
- 视频配音变声用什么软件?这些软件能帮助你
- 【最新技术早知道】PCIe Gen5 还没用上,Gen6 就来了?PCIe 6.0 系列文章之:《PCIe 6.0,到底 6 在哪?》
- 同源策略和跨域解决方案
- 关于实现手机定位,通过服务器,再发送给查询者,或指定人
- 金融机构的IT团队前置
- Python自动化测试框架之Pytest相关用法-基本使用(1)
- 【数学基础知识】证明三角形的三条垂线交于一点