简介

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

RSA算法基于一个十分简单的数论事实:将两个大质数相乘十分容易,但是想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。此博文旨在实现具体用法,对算法原理不作阐述,算法详情请百度~

非对称加密 VS 对称加密 VS 不可逆加密

对称加密是因为加密和解密的钥匙相同,而非对称加密是加密和解密的钥匙不同。对称和非对称加密都是可逆的(因为有密钥对,一个负责加密,一个负责解密)。

对称加密

对称加密称为密钥加密,速度快,但加密和解密的钥匙必须相同,只有通信双方才能知道密钥,常见的有DES,3DES,AES对称加密。

非对称加密

非对称加密称为公钥加密,算法更加复杂,速度慢,加密和解密钥匙不相同,任何人都可以知道公钥,只有一个人持有私钥可以解密。常见的就是RSA了。

不可逆加密

还有一种加密方法:不可逆加密。典型的代表就是MD5加密了。

对称加密算法、非对称加密算法和不可逆加密算法可以分别应用于数据加密、身份认证和数据安全传输。

使用场景

使用场景就太多了,网络交互时,我们希望数据能经过加密后再传输,比如账户密码之类~

加解密的两种实现方式

RSA非对称加密,在我们具体实现的环境中,有两种方法,通过文件形式和字符串形式。

通过文件加解密

我们可以通过将公钥和私钥以文件形式保存,对某些需要加密的字符串进行加解密~

import org.apache.commons.codec.binary.Base64;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map; /**
* 非对称加密算法RSA算法组件
* 非对称算法一般是用来传送对称加密算法的密钥来使用的,相对于DH算法,RSA算法只需要一方构造密钥,不需要
* 大费周章的构造各自本地的密钥对了。DH算法只能算法非对称算法的底层实现。而RSA算法算法实现起来较为简单
*
* @author kongqz
*/
public class RSACoder { //非对称密钥算法
public static final String KEY_ALGORITHM = "RSA"; /**
* 密钥长度,DH算法的默认密钥长度是1024
* 密钥长度必须是64的倍数,在512到65536位之间
*/
private static final int KEY_SIZE = 512;
//公钥
private static final String PUBLIC_KEY = "RSAPublicKey"; //私钥
private static final String PRIVATE_KEY = "RSAPrivateKey"; /**
* 初始化密钥对
*
* @return Map 甲方密钥的Map
*/
public static Map<String, Object> initKey() throws Exception {
//实例化密钥生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
//初始化密钥生成器
keyPairGenerator.initialize(KEY_SIZE);
//生成密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//甲方公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
//甲方私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
//将密钥存储在map中
Map<String, Object> keyMap = new HashMap<String, Object>();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap; } /**
* 私钥加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPrivateKey(byte[] data, byte[] key) throws Exception { //取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
//数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
} /**
* 公钥加密
*
* @param data 待加密数据
* @param key 密钥
* @return byte[] 加密数据
*/
public static byte[] encryptByPublicKey(byte[] data, byte[] key) throws Exception { //实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//初始化公钥
//密钥材料转换
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
//产生公钥
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec); //数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
return cipher.doFinal(data);
} /**
* 私钥解密
*
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
*/
public static byte[] decryptByPrivateKey(byte[] data, byte[] key) throws Exception {
//取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
//数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
} /**
* 公钥解密
*
* @param data 待解密数据
* @param key 密钥
* @return byte[] 解密数据
*/
public static byte[] decryptByPublicKey(byte[] data, byte[] key) throws Exception { //实例化密钥工厂
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
//初始化公钥
//密钥材料转换
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(key);
//产生公钥
PublicKey pubKey = keyFactory.generatePublic(x509KeySpec);
//数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, pubKey);
return cipher.doFinal(data);
} /**
* 取得私钥
*
* @param keyMap 密钥map
* @return byte[] 私钥
*/
public static byte[] getPrivateKey(Map<String, Object> keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
} /**
* 取得公钥
*
* @param keyMap 密钥map
* @return byte[] 公钥
*/
public static byte[] getPublicKey(Map<String, Object> keyMap) throws Exception {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
} /**
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
//初始化密钥
//生成密钥对
Map<String, Object> keyMap = RSACoder.initKey();
//公钥
byte[] publicKey = RSACoder.getPublicKey(keyMap); //私钥
byte[] privateKey = RSACoder.getPrivateKey(keyMap);
System.out.println("公钥:/n" + Base64.encodeBase64String(publicKey));
System.out.println("私钥:/n" + Base64.encodeBase64String(privateKey)); System.out.println("================密钥对构造完毕,甲方将公钥公布给乙方,开始进行加密数据的传输=============");
String str = "RSA密码交换算法";
System.out.println("/n===========甲方向乙方发送加密数据==============");
System.out.println("原文:" + str);
//甲方进行数据的加密
byte[] code1 = RSACoder.encryptByPrivateKey(str.getBytes(), privateKey);
System.out.println("加密后的数据:" + Base64.encodeBase64String(code1));
System.out.println("===========乙方使用甲方提供的公钥对数据进行解密==============");
//乙方进行数据的解密
byte[] decode1 = RSACoder.decryptByPublicKey(code1, publicKey);
System.out.println("乙方解密后的数据:" + new String(decode1) + "/n/n"); System.out.println("===========反向进行操作,乙方向甲方发送数据==============/n/n"); str = "乙方向甲方发送数据RSA算法"; System.out.println("原文:" + str); //乙方使用公钥对数据进行加密
byte[] code2 = RSACoder.encryptByPublicKey(str.getBytes(), publicKey);
System.out.println("===========乙方使用公钥对数据进行加密==============");
System.out.println("加密后的数据:" + Base64.encodeBase64String(code2)); System.out.println("=============乙方将数据传送给甲方======================");
System.out.println("===========甲方使用私钥对数据进行解密=============="); //甲方使用私钥对数据进行解密
byte[] decode2 = RSACoder.decryptByPrivateKey(code2, privateKey); System.out.println("甲方解密后的数据:" + new String(decode2));
}
}

转载自:https://blog.csdn.net/a394268045/article/details/52232120

代码转载自:https://www.cnblogs.com/frank-quan/p/7073457.html

java加密算法相关的更多相关文章

  1. java加密算法入门(二)-对称加密详解

    1.简单介绍 什么是对称加密算法? 对称加密算法即,加密和解密使用相同密钥的算法. 优缺点: 优点:算法公开.计算量小.加密速度快.加密效率高. 缺点: (1)交易双方都使用同样钥匙,安全性得不到保证 ...

  2. java加密算法入门(三)-非对称加密详解

    1.简单介绍 这几天一直在看非对称的加密,相比之前的两篇内容,这次看了两倍多的时间还云里雾里的,所以这篇文章相对之前的两篇,概念性的东西多了些,另外是代码的每一步我都做了介绍,方便自己以后翻阅,也方便 ...

  3. JAVA开发相关

    JAVA开发相关1. IntelliJ IDEA开发工具熟练使用2. Maven3. Spring框架(IoC.AOP) 1)数据库相关MyBatis 2)数据库连接池 3)事务.多数据源.跨数据库分 ...

  4. 获取Java系统相关信息

    package com.test; import java.util.Properties; import java.util.Map.Entry; import org.junit.Test; pu ...

  5. Java加密算法 RSA

    Java加密算法 RSA 2015-06-06 08:44 511人阅读 评论(0) 收藏 举报  分类: JAVA(57)  公钥加密也称为非对称加密.速度慢.加密和解密的钥匙不相同,某一个人持有私 ...

  6. java接口相关例题

    java接口相关习题 interface Graphics{  //接口里面只能用抽象方法  public abstract double area();    }//设置 平面类class Plan ...

  7. MD5加盐 Java加密算法

    MD5带盐值的java加密算法   import java.security.MessageDigest; public class PasswordEncoder { private final s ...

  8. java线程相关

    java线程相关 java 线程 1 线程的状态 This is an example of UML protocol state machine diagram showing thread sta ...

  9. 基本的java加密算法MD5等等

    简单的java加密算法有: BASE64       严格地说,属于编码格式,而非加密算法 MD5             (Message Digest algorithm 5,信息摘要算法) SH ...

随机推荐

  1. Phoenix设置联合主键

    1例如 create table test12(email varchar not null,id integer not null,name varchar not null,age integer ...

  2. ProgressDialog 进度条的初步认识

    public class MainActivity extends Activity implements View.OnClickListener{ private ProgressBar prog ...

  3. TensorFlow可以在终端和通过终端打开的PyCharm中运行,不能在直接打开的PyCharm中运行

    然后看运行窗口的出错信息,点击最右边的view,发现缺少个文件,如代码所示 Traceback (most recent call last): File "/usr/local/lib/p ...

  4. 多线程(四)wait()、notify()以及notifyAll()

    六.线程的等待和唤醒 1.wait()和notify()的简单示范 public class Wait extends Thread{ public synchronized void run() { ...

  5. qt一些函数

    sleep(n);   休息ns msleep(1000);   休息1000毫秒 usleep(1000000);  //休息n微妙

  6. java中简单的反射

    1.为什么会用到反射机制? 最近需要写定时服务,如果一个一个去写定时服务的话,后期维护是很烦人的,通过反射机制,我们就可以将定时服务的信息通过数据配置来实现,这样我们后期就可以将整个模块交给运维人员去 ...

  7. 【Winfrom-Button】 重写Button,去掉获取焦点时的边框

    Winfrom Button 去掉获取焦点时的边框: 自定义一个Button,重写ShowFocusCues方法 /// <summary> /// 去掉获取焦点的边框 /// </ ...

  8. 配置Multipath多路径环境

    iscsi服务器      eth0:192.168.4.5/24  eth1:192.168.2.5/24 iscsi客户端      eth0:192.168.4.100/24  eth3:201 ...

  9. wind本地MySQL数据到hive的指定路径

    一:使用:kettle:wind本地MySQL数据到hive的指定路径二:问题:没有root写权限网上说的什么少jar包,我这里不存在这种情况,因为我自己是导入jar包的:mysql-connecto ...

  10. B/S上传超大文件解决方案

    4GB以上超大文件上传和断点续传服务器的实现 随着视频网站和大数据应用的普及,特别是高清视频和4K视频应用的到来,超大文件上传已经成为了日常的基础应用需求. 但是在很多情况下,平台运营方并没有大文件上 ...