RSA加密&解密【Java&Scala】
一.简介
RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。
RSA公开密钥密码体制。所谓公开密钥密码体制就是使用不同的加密密钥与解密密钥,是一种“由已知加密密钥推导出解密密钥在计算上是不可行的”密码体制。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,由于无法计算出大数n的欧拉函数phi(N),所以不能根据PK计算出SK。
RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。RSA是被研究得最广泛的公钥算法,从提出到现今的三十多年里,经历了各种攻击的考验,逐渐为人们接受,截止2017年被普遍认为是最优秀的公钥方案之一。
二.代码实现【Java版】
package cn.ai; import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
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.HashMap;
import java.util.Map; import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException; import org.apache.commons.codec.binary.Base64; public class RSACrypt { private static Map<Integer, String> keyMap = new HashMap<Integer, String>(); /**
* 初始化生成公钥和私钥
* @throws NoSuchAlgorithmException
*/
public static void init() throws NoSuchAlgorithmException{
/**
* KeyPairGenerator用于生成公钥和私钥对,基于RSA算法生成对象
*/
KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
/**
* 初始化秘钥对生成器,秘钥大小为1024位
*/
keyPairGen.initialize(1024, new SecureRandom());
/**
* 生成秘钥
*/
KeyPair keyPair = keyPairGen.generateKeyPair();
/**
* 获取私钥
*/
RSAPrivateKey privateKey = (RSAPrivateKey)keyPair.getPrivate();
String privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded()));
/**
* 获取公钥
*/
RSAPublicKey publicKey = (RSAPublicKey)keyPair.getPublic();
String publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded())); /**
* 保存公钥,私钥
*/
keyMap.put(0, publicKeyStr); // 公钥
keyMap.put(1, privateKeyStr);// 私钥
} /**
* 公钥加密
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws Exception
*/
public static String rsaEncrypt(String content, String publicKey) throws InvalidKeySpecException, NoSuchAlgorithmException, Exception{
//base64编码的公钥
byte[] encoded = Base64.decodeBase64(publicKey);
RSAPublicKey rsaPublicKey = (RSAPublicKey)KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(encoded));
// RSA加密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey); String outPublicKey = Base64.encodeBase64String(cipher.doFinal(content.getBytes("UTF-8"))); return outPublicKey;
} /**
* 私钥解密
* @throws UnsupportedEncodingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws Exception
*/
public static String rsaDecrypt(String content, String privateKey) throws UnsupportedEncodingException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException{
//base64位解码加密后的字符串
byte[] inputByte = Base64.decodeBase64(content.getBytes("UTF-8"));
//base64编码的私钥
byte[] decoded = Base64.decodeBase64(privateKey);
RSAPrivateKey rsaPrivateKey = (RSAPrivateKey)KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
//RSA解密
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey);
String outPrivateKey = new String(cipher.doFinal(inputByte));
return outPrivateKey;
} public static void main(String[] args) throws Exception {
/**
* 初始化生成公钥,私钥
*/
init();
/**
* 加密数据
*/
String message = "abc123";
System.out.println("随机生成的公钥为:" + keyMap.get(0));
System.out.println("随机生成的私钥为:" + keyMap.get(1)); System.out.println("加密前的数据:" + message);
String messageEncrypt = rsaEncrypt(message, keyMap.get(0));
System.out.println("加密后的数据:" + messageEncrypt); //String mid = "MIIc" + keyMap.get(1).substring(4, keyMap.get(1).length());
//System.out.println("随机生成的私钥为:" + mid);
String messageDecrypt = rsaDecrypt(messageEncrypt, keyMap.get(1));
System.out.println("解密后的数据:" + messageDecrypt);
} }
三.结果【Java版】
1 随机生成的公钥为:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzveY+Gdrm4gY2IGT+M1yESXHPLSS7Nq/iex4h2oI3x0kSvYOoepQSPUhZvnUJEsrnYHKI9CZPJXNchqQFdR2Zy70GX/58yA700PVpk278z32aZ4OFkqhrmtULRiwF/ILpjucr7dIrgOU+hFTKHHc0fqhtHVWZVYcf1ZyKP8fQBwIDAQAB
2 随机生成的私钥为:MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALO95j4Z2ubiBjYgZP4zXIRJcc8tJLs2r+J7HiHagjfHSRK9g6h6lBI9SFm+dQkSyudgcoj0Jk8lc1yGpAV1HZnLvQZf/nzIDvTQ9WmTbvzPfZpng4WSqGua1QtGLAX8gumO5yvt0iuA5T6EVMocdzR+qG0dVZlVhx/VnIo/x9AHAgMBAAECgYAV9yoRAsXem1aY/MJ60joHLJaM8/5eJqO98L/Q8UwilucWNDTHvRslU3npBb51umczeXTlybh4yaHcd9PJmvNf6LI0LsCAWEqW6Y4/1kX2ro8w/a5uLLZMECa9q0xkn0+QWMMrcHxzUVhlott5lDx9ejiW+a3KpNscQLSxgZSeAQJBAN2N45wUFSvcGFZAOwHL6YpCIrECokdhFFp+eABPYJb+rDFfFyiiK8THk/osD2l0Tqtdl+mPJEAbXU1aK0VdnQECQQDPr9OwC0rpvttzq6TiEJ4S1Dz3kZwS2NkrukbgqWkGpC7HggBjYYyrujoEpEnPvqnm6oTWCDqh+YRWC6RMp4UHAkAJCwiWT0+J6cLoilieOyd+KDLoTLY4+aJuCyl0wcisgRqgLURxuSTWNFs649+BK2kmn3xa4SfWogdN5/dKLocBAkACeZjvNyM8Z97boQcE/qezl73mQWD3xIfKAp1Hnh03TAuWqxDwHkB752s7lO2gQShrLQ5KMqzoMz4FfHwHwdNPAkEAtNG3NONm0f4McwEYyxXkrlLWisf67xkTo6rLfxnf7f+xk8W6u6kf339AZlfOUv5I1BZKfka3hUxaXlpsYmQ0Xg==
3 加密前的数据:abc123
4 加密后的数据:s4P8ihNvDHdqB3libM2lj8eC37TQK/UBrUIKM4If42oMYiCVo/4q07FPLfDYCBMEa9sbdDSFA1mcXiWRvwIH+658Nu+dLSe1SQfuwI+7q0KbP0lQeCh3SkBvTqAt0BmEnpDvSUzn1FH/W8Wlqet9IBsTU7mZioXZ9jCSTvKvU8w=
5 解密后的数据:abc123
四.代码实现【Scala版】
package big.data.analyse.encryption import java.security.spec.{PKCS8EncodedKeySpec, X509EncodedKeySpec}
import java.security.{KeyFactory, SecureRandom, KeyPairGenerator}
import javax.crypto.Cipher import org.apache.commons.codec.binary.Base64 /**
* Created by zhen on 2019/6/15.
*/
object RSA {
var keyMap : Map[Int, String] = Map() /**
* 初始化公钥,私钥
*/
def init(): Unit ={
val keyPairGenerator = KeyPairGenerator.getInstance("RSA")
keyPairGenerator.initialize(1024, new SecureRandom())
val keyPair = keyPairGenerator.generateKeyPair()
val privateKey = keyPair.getPrivate
val privateKeyStr = new String(Base64.encodeBase64(privateKey.getEncoded)) val publicKey = keyPair.getPublic
val publicKeyStr = new String(Base64.encodeBase64(publicKey.getEncoded)) keyMap += (0 -> publicKeyStr) // 0表示公钥
keyMap += (1 -> privateKeyStr) // 1表示私钥
} /**
* 公钥加密
*/
def rsaEncrypt(content : String, publicKey : String): String ={
val encoded = Base64.decodeBase64(publicKey)
val rsaPublicKey = KeyFactory.getInstance("RSA").generatePublic(new X509EncodedKeySpec(encoded)) val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.ENCRYPT_MODE, rsaPublicKey) val enContent = Base64.encodeBase64String(cipher.doFinal(content.getBytes("UTF-8"))) return enContent
} /**
* 私钥解密
*/
def rsaDecrypt(content : String, privateKey : String): String ={
val bytes = Base64.decodeBase64(content.getBytes("UTF-8"))
val decoded = Base64.decodeBase64(privateKey)
val rsaPrivateKey = KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded)) val cipher = Cipher.getInstance("RSA")
cipher.init(Cipher.DECRYPT_MODE, rsaPrivateKey) val deContent = new String(cipher.doFinal(bytes)) return deContent
} /**
* 测试
* @param args
*/
def main(args: Array[String]) { /**
* 初始化加密算法
*/
init()
println("公钥:" +keyMap.get(0).get+ "\n私钥:" + keyMap.get(1).get) /**
* 加密内容
*/
val content = "abc123"
println("加密前的数据:" + content) /**
* 加密
*/
val enContent = rsaEncrypt(content, keyMap.get(0).get)
println("加密后的数据:" + enContent) /**
* 解密
*/
val deContent = rsaDecrypt(enContent, keyMap.get(1).get)
println("解密后的数据:" + deContent)
}
}
五.结果【Scala版】
公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCpWv6go/JB6/fgkFobB8UNG9yGEPEdJnRxy26YISXb2ACRvC1BZ4bKECdnVk5EMwEyIxtfYLbvf0PjVq1CYAimYd6D97teWSQM0ZsdYYzUeSz+KJABugt4A4LNitnfmn1jOToSdjlXZIlrzKQtNxXi4fEFHqg5CMUgrbU40amrcQIDAQAB
私钥:MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAKla/qCj8kHr9+CQWhsHxQ0b3IYQ8R0mdHHLbpghJdvYAJG8LUFnhsoQJ2dWTkQzATIjG19gtu9/Q+NWrUJgCKZh3oP3u15ZJAzRmx1hjNR5LP4okAG6C3gDgs2K2d+afWM5OhJ2OVdkiWvMpC03FeLh8QUeqDkIxSCttTjRqatxAgMBAAECgYAOIpgqFET+F5Hi3mmG5AkgZPjs/7EAO9twPAiJDgs45Dh38XrdgKSRbPO8/kkeDBvHcYKxXUMnjjm+WdewOI/AIJfhRD4dSW7vLEhDAD/sWN2gop34uFLIwFI4XESvdlObqFU082HqsiC6qP4b2/W5S5JDSx2kQaRLppl1/wX6mQJBANdhmlp2S3aHalKqdViTyLmwqDmQQQDCrdLUs0BCJIJBaRWiN5EbLeCF4EtbCN8Pe6KtiV1R1ZnAlvm7dVlCldMCQQDJS09ybefxe/CApr6ppK7bwSf2vVOqDO2dBm46oapK6otpSSt1USvah0yGNenu7hoPFFyFe3vlrbV3dQJBFdsrAkEAv67Xxma9ZnHCCGw4H2r3G3vDW+esUlbwiFBQb4HuKBa6xUwnk/bSb532LlqInKyU5gT32Zu5NCsYso1JNPVzjQJBAJNruWKnxW/hAlFmTUq21m0Q+HDHVce7siYHOKFuFubJAZL5SH+iFAj2f//m6k3XSXRzyBLmTeX3I2i6ZA1AsYMCQQCXnuh0VjBTqSrvrEWXlnyiQ1cpQdmAhI6YlnKW3Mcd6jjekCjAG7CXU1N845Ax7btTlF1Ca+vwcaVzm0oF80mQ
加密前的数据:abc123
加密后的数据:jcSjLubNx/1Vk4FEWBwukb8FK3w/QMNZ6UY5lZxLuMxvQ+sl/9cndIh5wNRkzowxmxDQnNcMlUQ5qwIvKnExSVXfBuoRKBH7J+9q7yb1XQR+m+r53djTrNbV15wztHO7KDh4bhlUSbv217OkTdBMb8Exh4aKuih7cUdsD9XQ+60=
解密后的数据:abc123
RSA加密&解密【Java&Scala】的更多相关文章
- c# RSA 加密解密 java.net公钥私钥转换 要解密的模块大于128字节
有一个和接口对接的任务,对方使用的是java,我方使用的是c#,接口加密类型为RSA,公钥加密私钥解密. 然后就是解决各种问题. 1.转换对方的密钥字符串 由于c#里面需要使用的是xml各式的密钥字符 ...
- RSA加密解密及数字签名Java实现--转
RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院 ...
- (转)RSA加密解密及数字签名Java实现
转:http://my.oschina.net/jiangli0502/blog/171263?fromerr=hc4izFe2 RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rives ...
- RSA加密解密(转)
RSA加密解密 对于RSA产生的公钥.私钥,我们可以有两种方式可以对信息进行加密解密.私钥加密-公钥解密 和 公钥加密-私钥解密RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest) ...
- C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法
因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger ...
- C# Java间进行RSA加密解密交互
原文:C# Java间进行RSA加密解密交互 这里,讲一下RSA算法加解密在C#和Java之间交互的问题,这两天纠结了很久,也看了很多其他人写的文章,颇受裨益,但没能解决我的实际问题,终于,还是被我捣 ...
- C# Java间进行RSA加密解密交互(二)
原文:C# Java间进行RSA加密解密交互(二) 接着前面一篇文章C# Java间进行RSA加密解密交互,继续探讨这个问题. 在前面,虽然已经实现了C# Java间进行RSA加密解密交互,但是还是与 ...
- C# Java间进行RSA加密解密交互(三)
原文:C# Java间进行RSA加密解密交互(三) 接着前面一篇C# Java间进行RSA加密解密交互(二)说吧,在上篇中为了实现 /** * RSA加密 * @param text--待加密的明文 ...
- Java使用RSA加密解密签名及校验
RSA加密解密类: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ...
- C#-java RSA加密解密
using Org.BouncyCastle.Math; using Org.BouncyCastle.Crypto.Parameters; using Org.BouncyCastle.Securi ...
随机推荐
- 在 json4s 中自定义CustomSerializer
到目前为止,Scala 环境下至少存在6种 Json 解析的类库,这里面不包括 Java 语言实现的 Json 类库.所有这些库都有一个非常相似的抽象语法树(AST).而 json4s 项目旨在提供一 ...
- Centos7安装完成后设定基本的网络配置
Centos7设定网络 新安装的centos7,网络默认是不启动的,需要人为的手工修改配置文件,在这里把这个过程简要的记录一下. 设定ip地址与mac地址自定义 [root@web ~]# cd /e ...
- promise简单实现
function isFunction(fn){ return Object.prototype.toString.call(fn) === '[object Function]'; } let ST ...
- elasticsearch 搜索提示DSL
1,创建mapping: PUT /news_website { "mappings": { "news" : { "properties" ...
- (转)搭建Elasticsearch和kibana环境
搭建Elasticsearch和kibana环境 作者:IT云清 原文:https://blog.csdn.net/weixin_39800144/article/details/81162002 1 ...
- bootCDN引用的bootstrap前端框架套件和示例
这是bootCDN上引用的bootstrap前端框架套件,由多个框架组合而成,方便平时学习和测试使用.生产环境要仔细琢磨一下,不要用开发版,而要用生产版.bootCDN的地址是:https://www ...
- maven工程仿springboot手写代码区分开发测试生产
读取代码: package com.jz.compute.mc.v2.config; import java.util.Enumeration; import java.util.ResourceBu ...
- Linux安装kafka2.3.1基于Scala2.12
一,先从官网下载:http://kafka.apache.org/downloads 二,解压压缩包(虽然后缀是tgz,但和gz解压方式一样):然后mv kafka_2.12-2.3.1 /usr/l ...
- lua【卤鹅】总结
转自:https://www.cnblogs.com/reblue520/p/10767428.html 编写一个简单的hello world程序 test.lua 如果觉得简单,可以给一个for循环 ...
- SQL Server中的GAM页和SGAM页
简介 我们已经知道SQL Server IO最小的单位是页,连续的8个页是一个区.SQL Server需要一种方式来知道其所管辖的数据库中的空间使用情况,这就是GAM页和SGAM页. Global A ...