博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
RSA代码演示
阅读量:3942 次
发布时间:2019-05-24

本文共 9983 字,大约阅读时间需要 33 分钟。

RSA实例代码

通过上一篇的RSA算法原理了解之后,这里用一段简易的Java代码进行演示。

  1. 首先我们创建一个类,然后在main方法中通过BigInteger.probablePrime(int bitLength, Random rnd)方法生成两个素数

    System.out.println(BigInteger.probablePrime(10, new Random()));System.out.println(BigInteger.probablePrime(10, new Random()));// 613// 523

    这里我生成的两个素数为 613 523,然后将两个素数相乘,613 * 523 = 320599[数字1]

  2. 将两个素数分别减一相乘,612 * 522 = 319464[数字2]

  3. 再通过随机数生成一个公钥 757。这个数不能与两个素数相同且小于数字2

    System.out.println(BigInteger.probablePrime(10, new Random()));// 757
  4. 再通过下面的 for循环找出私钥。注意:公钥与私钥并非是一对的,也就是说一个公钥可以对应多个私钥。

    for (int i = 0; i < 846216; i++) {
    // 私钥满足条件:公钥产生私钥除以数字2余1 if (((757 * i) % 319464) == 1) {
    System.out.println("私钥为:" + i); // 95797、415261、734725 }}
  5. 在这里我们得到公钥和私钥后,就可以发送我们所需要发送的东西了

    比如我们发送一个密码,123456。通过模指运算来进行加密和解密。

    System.out.println(new BigInteger("123456").modPow(new BigInteger("757"), new BigInteger("320599"))); // 172243// 172243,这就是通过模指运算加密后的System.out.println(new BigInteger("172243").modPow(new BigInteger("95797"), new BigInteger("320599"))); // 172243解密后就是123456

完整代码:

public class RSA {
public static void main(String[] args) {
System.out.println(BigInteger.probablePrime(10, new Random())); System.out.println(BigInteger.probablePrime(10, new Random())); for (int i = 0; i < 846216; i++) {
// 私钥满足条件:公钥产生私钥除以数字2余1 if (((757 * i) % 319464) == 1) {
System.out.println("私钥为:" + i); // 95797、415261、734725 } } System.out.println("加密后:"); System.out.println(new BigInteger("123456").modPow(new BigInteger("757"), new BigInteger("320599"))); // 172243,这就是通过模指运算加密后我们所需发给银行的 System.out.println("解密后:"); System.out.println(new BigInteger("172243").modPow(new BigInteger("95797"), new BigInteger("320599"))); // 172243解密后就是123456 }}

标准的RSA算法模拟代码

导入第三方加密库的依赖

junit
junit
4.13
org.bouncycastle
bcprov-jdk16
1.46

创建 RSA的公钥和密钥的PSAKeyCreator类

import org.bouncycastle.jce.provider.BouncyCastleProvider;import java.security.*;import java.util.Base64;/** * Created by wb on 2020/9/4 0004 19:33 * * 创建 RSA的公钥和私钥 */public class RSAKeyCreator {
public static void main(String[] args) {
createKeyPairs(); } /* * 生成公钥和私钥 */ private static void createKeyPairs() {
Security.addProvider(new BouncyCastleProvider()); // KeyPairGenerator 密钥对的生成器 try {
// KeyPairGenerator.getInstance(algorithm): 需要放置一个字符串,也就是算法的名称 KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA"); // initialize(keysize, random): 密钥的大小,随机数 generator.initialize(512, new SecureRandom()); // 初始化 generator // 这里就可以通过 generator获取到密钥对(公钥、私钥) KeyPair pair = generator.generateKeyPair(); PublicKey publicKey = pair.getPublic(); // 返回一个公钥对象 PrivateKey privateKey = pair.getPrivate(); // 返回一个私钥对象 // 接下来就需要将公钥和私钥转换成可识别的字符串,这里就需要进行 Base64的编码 // 通过 Base64获取到一个编码对象,编码对象里面的一个编码方法就可以获得 publicKey.getEncoded()的字节数组 // 然后再将字节数组转换成 Base64的字符串 String strPublicKey = new String(Base64.getEncoder().encode(publicKey.getEncoded())); // 公钥字符串 String strPrivateKey = new String(Base64.getEncoder().encode(privateKey.getEncoded())); // 私钥字符串 System.out.println(strPublicKey); System.out.println(strPrivateKey); } catch (NoSuchAlgorithmException e) {
e.printStackTrace(); } }}

RSA加密/解密的RSAUtil工具类

import javax.crypto.Cipher;import java.nio.charset.StandardCharsets;import java.security.PrivateKey;import java.security.PublicKey;import java.util.Base64;/** * Created by wb on 2020/9/4 0004 19:33 * * 封装标准的 RSA加密/解密算法的工具类 */public class RSAUtil {
/* * RSA公钥加密 * * 参数:第一个是需要加密的明文字符串,第二参数是公钥对象 */ public static String publicKeyEncryptData(String data, PublicKey publicKey) {
try {
// Cipher密码对象 Cipher cipher = Cipher.getInstance("RSA"); // 通过公钥进行加密 cipher.init(Cipher.ENCRYPT_MODE, publicKey); // 加密后的字节数组 byte[] encryptData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); // 使用 utf-8字符编码加密 // 获取加密字符串的结果,并返回 return Base64.getEncoder().encodeToString(encryptData); } catch (Exception e) {
e.printStackTrace(); } return null; } /* * RSA私钥解密 * * 参数:第一个是需要加密后的字符串,第二参数是私钥对象 */ public static String privateKeyDecryptData(String encryptData, PrivateKey privateKey) {
try {
// Cipher密码对象 Cipher cipher = Cipher.getInstance("RSA"); // 通过私钥进行解密 cipher.init(Cipher.DECRYPT_MODE, privateKey); // 通过 Base64进行解码,然后返回一个字节数组 byte[] decryptData = cipher.doFinal(Base64.getDecoder().decode(encryptData)); // 转换成明文的字符串并返回 return new String(decryptData, StandardCharsets.UTF_8); // 使用 utf-8字符编码解密 } catch (Exception e) {
e.printStackTrace(); } return null; } // 扩展内容 /* * RSA私钥加密 * * 参数:第一个是需要加密的明文字符串,第二参数是私钥对象 */ public static String privateKeyEncryptData(String data, PrivateKey privateKey) {
try {
// Cipher密码对象 Cipher cipher = Cipher.getInstance("RSA"); // 通过公钥进行加密 cipher.init(Cipher.ENCRYPT_MODE, privateKey); // 加密后的字节数组 byte[] encryptData = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8)); // 使用 utf-8字符编码加密 // 获取加密字符串的结果,并返回 return Base64.getEncoder().encodeToString(encryptData); } catch (Exception e) {
e.printStackTrace(); } return null; } /* * RSA公钥解密 * * 参数:第一个是需要加密后的字符串,第二参数是公钥对象 */ public static String publicKeyDecryptData(String encryptData, PublicKey publicKey) {
try {
// Cipher密码对象 Cipher cipher = Cipher.getInstance("RSA"); // 通过私钥进行解密 cipher.init(Cipher.DECRYPT_MODE, publicKey); // 通过 Base64进行解码,然后返回一个字节数组 byte[] decryptData = cipher.doFinal(Base64.getDecoder().decode(encryptData)); // 转换成明文的字符串并返回 return new String(decryptData, StandardCharsets.UTF_8); // 使用 utf-8字符编码解密 } catch (Exception e) {
e.printStackTrace(); } return null; }}

RSA算法测试

import fun.wblog.utils.RSAUtil;import java.security.KeyFactory;import java.security.NoSuchAlgorithmException;import java.security.PrivateKey;import java.security.PublicKey;import java.security.spec.InvalidKeySpecException;import java.security.spec.PKCS8EncodedKeySpec;import java.security.spec.X509EncodedKeySpec;import java.util.Base64;/** * Created by wb on 2020/9/4 0004 20:06 */public class RSATest {
public static void main(String[] args) {
// 公钥字符串 String strPublicKey = "MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAJHXc9MzZLGNrs6nAB/PmaDopfOoOaiN9M+4ZSli/JW5XRx/2+DL8VPhOMadWiLUDYwtMjAlHO9YYOmAR+mIDKsCAwEAAQ=="; // 私钥字符串 String strPrivateKey = "MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAkddz0zNksY2uzqcAH8+ZoOil86g5qI30z7hlKWL8lbldHH/b4MvxU+E4xp1aItQNjC0yMCUc71hg6YBH6YgMqwIDAQABAkBOTqYlT+IQJ+glk6vQaNKvgFui4b/bziUV54eB2mGPLkFvbPPz6eEIu0XEvouBxGBxmgp/vMysEjDPzLcL8cIxAiEAzhNpbW5Yt4Hwej2JyHKsbHKPV1NaPp3gb4Cq9eJJMYMCIQC1LGIS+r2+e4hyPDEj4IFbjRxq2dRQ0CnlzHXo76WXuQIgYLTlXdBR29QjqQnl9eYymjXspJteF1J5d3oXQIpvtMcCIQCvu6JRyJdd+ZNLQyljJHQ1KnYDCtGPparONPm1/SZBOQIhAJpjZWIU3G8dAxtcdA7xhUOV4OiL/u8QPiOfSRjWZIjR"; // 公钥规则对象/公钥说明书对象 X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(strPublicKey.getBytes())); // 私钥规则对象/私钥说明书对象 PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(strPrivateKey.getBytes())); try {
// 密钥工厂对象 KeyFactory keyFactory = KeyFactory.getInstance("RSA"); // 通过 x509EncodedKeySpec规则生成公钥 PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec); // 通过 pkcs8EncodedKeySpec规则生成私钥 PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec); // ===================================================================// String data = "RSA加密解密算法@###123456%&"; // 明文 System.out.println("明文是: " + data); // 1.调用公钥加密方法 String encryptData = RSAUtil.publicKeyEncryptData(data, publicKey); System.out.println("公钥加密后: " + encryptData); // 2.调用私钥解密方法 String decryptData = RSAUtil.privateKeyDecryptData(encryptData, privateKey); System.out.println("私钥解密后: " + decryptData); // 扩展内容==========================================================// // 3.调用私钥加密方法 String encryptData2 = RSAUtil.privateKeyEncryptData(data, privateKey); System.out.println("私钥加密后: " + encryptData2); // 4.调用公钥解密方法 String decryptData2 = RSAUtil.publicKeyDecryptData(encryptData2, publicKey); System.out.println("公钥解密后: " + decryptData2); } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
e.printStackTrace(); } }}

https://i.loli.net/2020/09/05/TyZPsoczardQU89.gif

RSA算法演示.gif

总结:

先通过KeyPairGenerator来生成密钥对,然后再去封装加密和解密的方法。

在工具类中最主要的实现加密和解密的关键的对象是靠Cipher密码对象通过getInstance()去找它的这个密码算法,然后实现了这个对象。这个对象的关键一点就是有两个常量,一个常量是ENCRYPT_MODE加密模式,一个常量是DECRYPT_MODE解密模式。

然后在使用的过程再去将我们的公钥和私钥字符串,把它转成一个公钥对象和私钥对象,那么如何将公钥字符串/私钥字符串转成公钥对象/私钥对象呢?那么就要使用到了一个公钥规则对象(公钥说明书X509EncodedKeySpec)/私钥规则对象(私钥说明书PKCS8EncodedKeySpec)。拿到这个说明书对象,我们最终的主要目的就是通过KeyFactory去生成一个公钥对象和私钥对象,这样就可以使用我们之前封装的加密解密工具了。从而对我们的明文进行加密和解密。

转载地址:http://xziwi.baihongyu.com/

你可能感兴趣的文章
Vue3.0+Vite2.0项目框架搭建(二)- 引入axios
查看>>
Vue3.0+Vite2.0项目框架搭建(三)- 引入Element3
查看>>
使用Vue CLI v4.5(+)搭建Vue3.0项目框架搭建
查看>>
Java集合框架
查看>>
线程协作与生产者消费者问题
查看>>
Vue入门
查看>>
非starter方式实现springboot与shiro集成
查看>>
Starter方式实现Springboot与Shiro集成
查看>>
移动端多页面应用(MPA)的开发(一)
查看>>
移动端多页面应用(MPA)的开发(二)
查看>>
移动端多页面应用(MPA)的开发(三)
查看>>
移动端多页面APP(MPA)开发体验
查看>>
基于深度学习知识追踪研究进展(综述)数据集模型方法
查看>>
linux常见命令与FileZilla
查看>>
PostgreSQL和ElasticSearch学习笔记
查看>>
java反射
查看>>
paint 和 paintcomponent的区别
查看>>
JSP字节码的存放路径问题
查看>>
对RMQ的理解
查看>>
LCA的离线算法
查看>>