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加密与安全相关推荐

  1. DSA签名算法 - Java加密与安全

    DSA签名算法DSA就是Digital Signature Algorithm,他使用的是EIGamal数字签名算法DSA只能配合SHA使用:1. 所以有SHA1withDSA2. SHA256wit ...

  2. 第十九篇:JAVA加密解密之RSA算法

    RSA算法简介 RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.1987年首 ...

  3. RSA签名算法,计算调用加密报文,安全传输

    RSA签名算法 1. 获取当前的时间戳参数 2. 计算参数签名 3. 获取请求对象的MD5密文 4. 通过私钥计算某个参数的RSA签名 5. 转换字符集到utf8 6. MD5加密字符串 7. bas ...

  4. Java 加密解密 对称加密算法 非对称加密算法 MD5 BASE64 AES RSA

    [最简单的加密] 1.简单的概念 明文:加密前的信息 密文:机密后的信息 算法:加密或解密的算法 密钥:算法使用的钥匙(读作miyao,正确应该是miyue,但是大家都读miyao) 2.简单的例子 ...

  5. 非对称加密下RSA在Java的简明教程

    引言 在现实世界中,每个人都有自己的密码.在各种系统中都有各类加密和解密的需求. 本文将详细介绍一下RSA的前身后世,应用场景和在Java中的实现,从理论到实践,一步到位,触手可用. 非对称加密与对称 ...

  6. Java加密技术(四)——非对称加密算法RSA

    转自:http://snowolf.iteye.com/blog/381767 接下来我们介绍典型的非对称加密算法--RSA RSA     这种算法1978年就出现了,它是第一个既能用于数据加密也能 ...

  7. Java进阶(七)Java加密技术之非对称加密算法RSA

    Java加密技术(四)--非对称加密算法RSA 非对称加密算法--RSA 基本概念 非对称加密算法是一种密钥的保密方法. 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(priv ...

  8. 非对称加密——RSA算法JAVA代码实践

    文章目录 说明 RSA加解密 测试代码 打印输出 说明 1:下面代码参考自<JAVA加密解密的艺术>,有部分修改,详见原理见原书 2:下面代码是RSA在JAVA中API级别的代码实现,具体 ...

  9. RSA node解密 java 加密的注意事项

    java 代码 Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding"); 代替 Cipher.getInstance(&q ...

最新文章

  1. 查询服务器上几张显卡命令
  2. 西门子获首都机场18亿大单
  3. 腾讯与中国人民大学开源最新研究成果:3TS腾讯事务处理技术验证系统
  4. web.xml文件的作用
  5. ShadeGraph教程之节点详解1:Artistic Nodes
  6. Oracle学习总结(7)—— 常用的数据库索引优化语句总结
  7. git merge 的撤销
  8. 零基础学python用哪本书好-零基础想要学习Python编程 ,不知道看哪本书?
  9. ARM中的RO、RW和ZI DATA说明
  10. 下载 / 安装 Visual Studio - C语言零基础入门教程
  11. matlab 博弈论代码,各种博弈论详解(示例代码)
  12. MySQL 事务四大特性和事务隔离级别
  13. 科学技术法-正则表达式-QT
  14. 视频配音变声用什么软件?这些软件能帮助你
  15. 【最新技术早知道】PCIe Gen5 还没用上,Gen6 就来了?PCIe 6.0 系列文章之:《PCIe 6.0,到底 6 在哪?》
  16. 同源策略和跨域解决方案
  17. 关于实现手机定位,通过服务器,再发送给查询者,或指定人
  18. 金融机构的IT团队前置
  19. Python自动化测试框架之Pytest相关用法-基本使用(1)
  20. 【数学基础知识】证明三角形的三条垂线交于一点

热门文章

  1. MySQL纯透明的分库分表技术还没有
  2. IBM AIX服务器分区之间迁移IO设备以迁移HBA卡为例
  3. windows(64位)下使用curl命令
  4. vim 粘贴代码格式
  5. IIS 7.5 Express概况
  6. nltk book的下载
  7. Linux高可用性方案之Heartbeat的CRM节点得分计算(原创)
  8. find : 路径必须在表达式之前
  9. 个人对持续集成的理解和实践
  10. 小型车、中型车、大型车、重型车的区分和定义见下表: