RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。1987年7月首次在美国公布,当时他们三人都在麻省理工学院工作实习。RSA就是他们三人姓氏开头字母拼在一起组成的。

RSA是目前最有影响力和最常用的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密标准。

RSA公开密钥密码体制。所谓的公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。

在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK。

基于这种理论,1978年出现了著名的RSA算法,它通常是先生成一对RSA 密钥,其中之一是保密密钥,由用户保存;另一个为公开密钥,可对外公开,甚至可以在网络服务器中注册。为提高保密强度,RSA密钥至少为500位长,一般推荐使用1024位。这就使加密的计算量很大。

RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,截止2017年被普遍认为是最优秀的公钥方案之一。

SET(Secure Electronic Transaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。RSA密钥长度随着保密级别提高,增加很快。

RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。

我们接下来看下Java中如何实现RSA加密解密与加签验签。我们先来看RSA加密解密。

1 import javax.crypto.BadPaddingException;2 import javax.crypto.Cipher;3 import javax.crypto.IllegalBlockSizeException;4 import javax.crypto.NoSuchPaddingException;5 import java.security.*;6 import java.util.Base64;7 /**8 * RSA加密解密操作步骤9 */

10 public classTest1 {11 public static voidmain(String[] args) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {12 //先给出一个待加密的字符串

13 String data="青青子衿,悠悠我心。但为君故,沉吟至今。";14 //1.构建公私钥匙对

15 KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");16 KeyPair keyPair =keyPairGenerator.generateKeyPair();17 //2.获取钥匙对中的公钥

18 PublicKey publicKey =keyPair.getPublic();19 //3.获取钥匙对中的私钥

20 PrivateKey privateKey =keyPair.getPrivate();21 //4.对待加密的数据进行加密

22 Cipher cipher = Cipher.getInstance("RSA");23 cipher.init(Cipher.ENCRYPT_MODE,publicKey);24 byte[] bytesEncrypt = cipher.doFinal(data.getBytes());//产生的是乱码,需要用Base64进行转码25 //5.Base64编码

26 byte[] encodeBase64 =Base64.getEncoder().encode(bytesEncrypt);27 System.out.println("加密后的数据:"+newString(encodeBase64));28 //6.在解密时,先对用Base64编码的信息进行解码

29 byte[] bytesDecode =Base64.getDecoder().decode(encodeBase64);30 //7.解密

31 Cipher cipher2=Cipher.getInstance("RSA");32 cipher2.init(Cipher.DECRYPT_MODE,privateKey);33 byte[] bytesDecrypt =cipher2.doFinal(bytesDecode);34 System.out.println("解密后的数据:"+newString(bytesDecrypt));35 }36 }

公钥和私钥本身存储的信息是乱码,在实际使用中,我们还可以通过Base64将这些乱码编码为可识别的ASCII码,然后将公钥和私钥信息持久化存储到文件中,在以后需要使用时,可以从文件中读取公钥和私钥信息。为此,我们可以写一个RSA的工具类,从一个储存公钥和私钥信息的文件里读取公钥和私钥信息,然后定义获取公钥和私钥的方法,以及加密和解密数据的方法。首先,我们提供一对公私钥信息,假定公钥信息储存在一个名称为rsa_public_key.pem的文件里,信息如下:

-----BEGIN RSA PUBLIC KEY-----MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDY90KtriCa4KjNe3mgrGGbDB95

8A2byBKf+wOmPmOopP3gGeg7+DFAPNYCC+tL8h2bpUI3IPKOm2Hon8kM/p628i1J

Z7JjopYVZW6JKqA2ImyneeUEK748FXwXTRAAMCTqQG/7a178BGawTdHi6hk+M6UF

lT0EhL6JA8ULKFoiHwIDAQAB-----BEGIN RSA PUBLIC KEY-----

假定私钥信息储存在一个名称为rsa_private_key.pem的文件里,信息如下::

-----BEGIN RSA PRIVATE KEY-----MIICXQIBAAKBgQDY90KtriCa4KjNe3mgrGGbDB958A2byBKf+wOmPmOopP3gGeg7+DFAPNYCC+tL8h2bpUI3IPKOm2Hon8kM/p628i1JZ7JjopYVZW6JKqA2ImyneeUE

K748FXwXTRAAMCTqQG/7a178BGawTdHi6hk+M6UFlT0EhL6JA8ULKFoiHwIDAQAB

AoGBAIJFhF2wLZeQyQoH13Gnzzs/Pi8C+cjNipFQMFLDJyd9WYoTRCOt1DST0pOM

AI2rJCfuRCHBwKHrnhAE0LzirPxkmvyHTIBXIoz3fHiSkIKkUVG04BcgTYpNKWPB

ISlzdhSaw7CnmJjTthTrD5LLPtpqUl350lUYFEHVNR6Ys9JRAkEA9JUEVxzSvQkV

V6hxhbvlxl0mATbPfiNKDBTPdr48dyYdgluAoGfAPf9rmgoCpdEd2hZBIfdy7xdL

LvP7ztb/rQJBAOMYNC/lZLz9A9cDJ5bibrJnmyRG0SAGAzu4ffYdBoGb0kRRKzTe

5jxfRnbiUPQU4GQXhADfikGn2ogRqbtDsnsCQQCJdp+D3n1LJanLJK75PQv9myjb

EdU4zdi2RZP85xrQ1KlNNORsQyO3NLFjWDD4xTmD83IUByGf43WsJBDoxcnZAkA3

i84IARX42/I6fz0JvOzSmmDqKKAyMwZLbz7wGf1jalet+iSVVAgAsFUt8wFWEl0o

XlAdXpAUqxfavGdFtLNNAkABS576xgLcLmyw51f9hoM9RiamLn+WNzoA5TLOZjGI

dZZnX/A8SoFYGoJoN1O0hp5DxDdl+gjW/mH51+gliEIB-----END RSA PRIVATE KEY-----

接下来,我们写一个RSAUtil工具类,代码如下:

1 import javax.crypto.BadPaddingException;2 import javax.crypto.Cipher;3 import javax.crypto.IllegalBlockSizeException;4 import javax.crypto.NoSuchPaddingException;5 import java.io.BufferedReader;6 import java.io.FileReader;7 import java.io.IOException;8 import java.security.*;9 import java.security.spec.InvalidKeySpecException;10 import java.security.spec.PKCS8EncodedKeySpec;11 import java.security.spec.X509EncodedKeySpec;12 import java.util.Base64;13 /**14 * 工具类15 */

16 public classRSAUtil {17 /*

18 读取秘钥数据19 */

20 public static byte[] readKeyDatas(String keyFilePath){21 BufferedReader bufferedReader=null;22 try{23 bufferedReader = new BufferedReader(newFileReader(keyFilePath));24 String str=null;25 StringBuilder stringBuilder=newStringBuilder();26 while ((str=bufferedReader.readLine())!=null){27 if(str.contains("---")){28 continue;29 }30 stringBuilder.append(str);31 }32 returnstringBuilder.toString().getBytes();33 }catch(IOException e) {34 e.printStackTrace();35 }finally{36 try{37 bufferedReader.close();38 } catch(IOException e) {39 e.printStackTrace();40 }41 }42 return null;43 }44 /*

45 生成公钥46 */

47 public staticPublicKey getPublicKey(String publicKeyPath){48 //1.读取公钥文件,获取公钥数据

49 byte[] bytesPublicBase64 =readKeyDatas(publicKeyPath);50 //2.对读取回来的数据进行Base64解码

51 byte[] bytesPublic =Base64.getDecoder().decode(bytesPublicBase64);52 //3.把解码后的数据,重新封装成一个PublicKey对象

53 X509EncodedKeySpec keySpec = newX509EncodedKeySpec(bytesPublic);54 KeyFactory keyFactory=null;55 try{56 keyFactory = KeyFactory.getInstance("RSA");57 PublicKey publicKey =keyFactory.generatePublic(keySpec);58 returnpublicKey;59 } catch(NoSuchAlgorithmException e) {60 e.printStackTrace();61 } catch(InvalidKeySpecException e) {62 e.printStackTrace();63 }64 return null;65 }66 /*

67 生成私钥68 */

69 public staticPrivateKey getPrivateKey(String privateKeyPath){70 //1.读取私钥文件,获取私钥数据

71 byte[] bytesPrivateBase64 =readKeyDatas(privateKeyPath);72 //2.对读取回来的数据进行Base64解码

73 byte[] bytesPrivate =Base64.getDecoder().decode(bytesPrivateBase64);74 //3.把解码后的数据,重新封装成一个PrivateKey对象

75 PKCS8EncodedKeySpec keySpec = newPKCS8EncodedKeySpec(bytesPrivate);76 KeyFactory keyFactory=null;77 try{78 keyFactory = KeyFactory.getInstance("RSA");79 PrivateKey privateKey =keyFactory.generatePrivate(keySpec);80 returnprivateKey;81 } catch(NoSuchAlgorithmException e) {82 e.printStackTrace();83 } catch(InvalidKeySpecException e) {84 e.printStackTrace();85 }86 return null;87 }88 /*

89 加密数据90 */

91 public staticString encodeData(PublicKey publicKey,String originData){92 try{93 Cipher cipher = Cipher.getInstance("RSA");94 cipher.init(Cipher.ENCRYPT_MODE,publicKey);95 byte[] bytesEncrypt =cipher.doFinal(originData.getBytes());96 //Base64编码

97 byte[] bytesEncryptBase64 =Base64.getEncoder().encode(bytesEncrypt);98 return newString(bytesEncryptBase64);99 } catch(NoSuchAlgorithmException e) {100 e.printStackTrace();101 } catch(NoSuchPaddingException e) {102 e.printStackTrace();103 } catch(InvalidKeyException e) {104 e.printStackTrace();105 } catch(BadPaddingException e) {106 e.printStackTrace();107 } catch(IllegalBlockSizeException e) {108 e.printStackTrace();109 }110 return null;111 }112 /*

113 解密数据114 */

115 public staticString decodeData(PrivateKey privateKey,String encodeData){116 try{117 //Base64解码

118 byte[] bytesEncrypt =Base64.getDecoder().decode(encodeData);119 //加密

120 Cipher cipher = Cipher.getInstance("RSA");121 cipher.init(Cipher.DECRYPT_MODE,privateKey);122 byte[] bytesDecrypt =cipher.doFinal(bytesEncrypt);123 return newString(bytesDecrypt);124 } catch(NoSuchAlgorithmException e) {125 e.printStackTrace();126 } catch(NoSuchPaddingException e) {127 e.printStackTrace();128 } catch(InvalidKeyException e) {129 e.printStackTrace();130 } catch(BadPaddingException e) {131 e.printStackTrace();132 } catch(IllegalBlockSizeException e) {133 e.printStackTrace();134 }135 return null;136 }137 }

这样的话,以后需要使用公钥和私钥,以及加密解密时,调用上述工具类中的相应方法即可。

最后,我们再来看用RSA如何对数据进行加签验签,具体代码如下:

1 import java.io.UnsupportedEncodingException;2 import java.security.*;3 /**4 * 加签 验签 签名验证:验证数据的合法来源 即验证数据来源的合法性5 * 加签:私钥6 * 验签:公钥7 */

8 public classTest2 {9 private static String privateKeyPath="储存私钥信息的文件路径";10 private static String publicKeyPath="储存公钥信息的文件路径";11 public static voidmain(String[] args) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException, SignatureException {12 String data="验证该数据是否为合法的服务器发送";13 /**14 * 加签过程15 */

16 PrivateKey privateKey =RSAUtil.getPrivateKey(privateKeyPath);17 Signature signature = Signature.getInstance("Sha1WithRSA");18 signature.initSign(privateKey);19 signature.update(data.getBytes("UTF-8"));20 byte[] signed =signature.sign();21 /**22 * 验签过程23 */

24 PublicKey publicKey =RSAUtil.getPublicKey(publicKeyPath);25 Signature signature2 = Signature.getInstance("Sha1WithRSA");26 signature2.initVerify(publicKey);27 signature2.update(data.getBytes("UTF-8"));28 boolean verify =signature2.verify(signed);29 System.out.println("验签结果:"+verify);30 }31 }

java rsa加密 加签_RSA加密解密与加签验签相关推荐

  1. RSA密钥生成、加密解密、数据签名验签

    公钥.私钥生成 准备工作,基础的帮助类 使用java代码生成公钥私钥 使用openssl生成公钥私钥 加解密 数据签名及验签 数据加解密及签名验签测试 注意项 公钥.私钥生成 准备工作,基础的帮助类 ...

  2. Java开发中的加密、解密、签名、验签,密钥,证书,这篇就够了,赶紧收藏起来

    OpenSSL和keytool 先说一下两个重要的工具 OpenSSL:OpenSSL整个软件包大概可以分成三个主要的功能部分:SSL协议库libssl.应用程序命令工具以及密码算法库libcrypt ...

  3. asp版 vbscript RSA公钥加密 / 私钥解密 / 私钥签名 / 公钥验签(支持中文)分段加密解密

    最近有空在把自己的asp站点后端函数全部整理了下,在弄RSA的时候遇到了坑了,然后找到下面这位兄弟刚好发布的文章: https://blog.csdn.net/todaygods/article/de ...

  4. RSA加密、解密、签名、验签介绍

    参考链接:https://www.cnblogs.com/pcheng/p/9629621.html RAS简介 RSA加密是非对称加密,由一对秘钥进行完成加密解密,分别称为公钥和私钥,公钥加密,私钥 ...

  5. 数字证书应用综合揭秘(包括证书生成、加密、解密、签名、验签)

    引言 数字证书是一个经证书授权中心数字签名的包含公开密钥拥有者信息以及公开密钥的文件.为现实网络安全化标准如今大部分的 B2B.B2C.P2P.O2O 等商业网站含有重要企业资料个人资料的信息资信网站 ...

  6. PHP 支付宝SDK加密与解密、签名与验签(含php原生写法)

    1.使用支付宝SDK,本次使用的SDK是老版 支付宝文档:https://opendocs.alipay.com/open/54/103419 首先下载或使用新上线的Web在线加密,生成应用私钥与应用 ...

  7. iOS 使用 SM2 SM4 加解密,SM2 签名验签及 SM3 签名

    前言 对于开发人员,开发中加解密是经常用到的,常见的密码算法 MD5.SHA.AES.DES,RSA 等等,这些无一例外都是国外的加密算法.基于安全和宏观战略考虑,我国从 2010 年先后推出了 SM ...

  8. ASP VBSCRIPT VBA RSA 公钥加密 私钥解密 私钥签名 公钥验签

    <% '@title: Class_Crypt_Rsa '@author: ekede.com '@date: 2020-10-28 '@description: RSA 公钥加密->私钥 ...

  9. STM32F103驱动RJMU401实现SM2加解密、签名与验签

    目录 前言 一.什么是加密.硬件加密以及加密芯片品牌? 二.开发记录 1.开发环境 2.开发流程 3.常见问题汇总 总结 前言 项目需要加密并且需要采用硬件加密,加密方式为非对称–SM2,之前只接触过 ...

最新文章

  1. hbuilderX的upx单位是什么鬼?
  2. 【SqlServer】SqlServer中的更新锁(UPDLOCK)
  3. 数学知识--Unconstrained Optimization(第一章)
  4. Windbg学习 (0x0001) 安装与基本配置
  5. bip动作捕捉_Mocap动作捕捉系列
  6. 文末彩蛋 | 这个 Request URL 长得好不一样
  7. php集成腾讯云im
  8. 《人类简史》读书笔记
  9. Python编写斗地主游戏(单机版)
  10. 谨以此辞职信祭奠我的第一份工作
  11. OpenEuler树莓派基础实验 20212802范辰宇
  12. python中get函数是什么意思_详解python中get函数的用法(附代码)_后端开发
  13. 十个人有多少种不同组合?
  14. 六种不同型号的电灯泡
  15. 活性DNA羟化酶 Tet1 活性测定
  16. 基于SPI协议的Flash驱动控制-数据普通读操作
  17. A股滚动净利润增速最高排名
  18. 百味勺子——环境搭建篇
  19. 高功率DC-DC4.5V-18V同步降压转换器18V600kHz2A输出电流参考资料
  20. 文章管理系统 -- Express学习

热门文章

  1. C++vector基础容器3.0
  2. opencv 创建调色板
  3. ubuntu安装opencv的c++开发环境
  4. 简单区分NMOS和PMOS的方法
  5. 利用Multisim快速分析一个RC电路
  6. ecshop mysql 标题表_ecshop商品分类列表页如何自定义title标题
  7. PHP/JS中获取当前页面的完整URL
  8. Eclipse 配置
  9. android之wifi开发
  10. Android UI 绘制过程浅析(二)onMeasure过程