一、概述
1.RSA是基于大数因子分解难题。目前各种主流计算机语言都支持RSA算法的实现
2.java6支持RSA算法
3.RSA算法可以用于数据加密和数字签名
4.RSA算法相对于DES/AES等对称加密算法,他的速度要慢的多
5.总原则:公钥加密,私钥解密 / 私钥加密,公钥解密

二、模型分析
RSA算法构建密钥对简单的很,这里我们还是以甲乙双方发送数据为模型
1.甲方在本地构建密钥对(公钥+私钥),并将公钥公布给乙方
2.甲方将数据用私钥进行加密,发送给乙方
3.乙方用甲方提供的公钥对数据进行解密

如果乙方向传送数据给甲方:
4.乙方用公钥对数据进行加密,然后传送给甲方
5.甲方用私钥对数据进行解密

三、代码分析

package com.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));
}
}

控制台输出:

公钥:/nMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAL/BGYIKZcuLuLdKN/AusrZyDLpwWHrMWiQ1KTOCFi434ymAWhK5R8NER3UvM6hF2zp0KYv1denqYwAx0NpR8XECAwEAAQ==
私钥:/nMIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAv8EZggply4u4t0o38C6ytnIMunBYesxaJDUpM4IWLjfjKYBaErlHw0RHdS8zqEXbOnQpi/V16epjADHQ2lHxcQIDAQABAkBC6wmS1zwVH6qT1IPW/wUBJKYKfmByYlRm5GJ/hjtlXyJrNqIphwHVH7vJmz+NBFhq7FxW1OeUEX7Ql2XP23ARAiEA8MS/G90F1so2FnsDI/xeDp9/5RlCY8M6xiF3y/XPapUCIQDL4pDlMxRwCtinuOSUYBKWBjAJRHJHrWgcoN7c1ydQbQIgALlGrcnDS7r94KFsB/6pNbgLBWBHD8+1bIULPCS4A+UCIQCui5aUQbibew2j+QvnYqBGw6FYLbrQVkotSCPDWIaVuQIhAOy0TAqBeaSp+bCl3GO5BH4AO49RN4SZKLXHGqgHlMYA
================密钥对构造完毕,甲方将公钥公布给乙方,开始进行加密数据的传输=============
/n===========甲方向乙方发送加密数据==============
原文:RSA密码交换算法
加密后的数据:BBUSQY2BEp2c0+vIZ0jBUpxOOzcZd6osRB3r8DFJwT7dRdr7/e5DkXjgV/txEDNlnzudIdMOOAIgEwmU8jt95g==
===========乙方使用甲方提供的公钥对数据进行解密==============
乙方解密后的数据:RSA密码交换算法/n/n
===========反向进行操作,乙方向甲方发送数据==============/n/n
原文:乙方向甲方发送数据RSA算法
===========乙方使用公钥对数据进行加密==============
加密后的数据:CvBzAaEYTBHYiVEFNSlpiNWZi3flvrh1Ye5t7GYsrUIOKek4QiQsbVnjsty8rKw2Wz1SXf/ozRhNvXMFqDsQpQ==
=============乙方将数据传送给甲方======================
===========甲方使用私钥对数据进行解密==============
甲方解密后的数据:乙方向甲方发送数据RSA算法

四、总结
1.RSA与DH算法不同,只需要一套密钥就能完成加密、解密的工作
2.通过代码能看出来,公钥长度明显小于私钥
3.遵循:公钥加密-私钥解密,私钥加密-公钥解密的原则
4.公钥和私钥肯定是完全不同

原文:http://www.jianshu.com/p/aff5492d64f0

测试无法使用:http://blog.csdn.net/a394268045/article/details/52232120

JAVA RSA非对称加密详解[转载]的更多相关文章

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

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

  2. Java中Volatile关键字详解(转载)

    转载自:https://www.cnblogs.com/zhengbin/p/5654805.html 一.基本概念 先补充一下概念:Java 内存模型中的可见性.原子性和有序性. 可见性: 可见性是 ...

  3. python logging模块详解[转]

    一.简单将日志打印到屏幕: import logging logging.debug('debug message') logging.info('info message') logging.war ...

  4. Objective-C之run loop详解[转]

    做了一年多的IOS开发,对IOS和Objective-C深层次的了解还十分有限,大多还停留在会用API的级别,这是件挺可悲的事情.想学好一门语言还是需要深层次的了解它,这样才能在使用的时候得心应手,出 ...

  5. bloom filter 详解[转]

    Bloom Filter概念和原理 焦萌 2007年1月27日 Bloom Filter是一种空间效率很高的随机数据结构,它利用位数组很简洁地表示一个集合,并能判断一个元素是否属于这个集合.Bloom ...

  6. PostgreSQL.conf文件配置详解[转]

    一.连接配置与安全认证 1.连接Connection Settings   listen_addresses (string) 这个参数只有在启动数据库时,才能被设置.它指定数据库用来监听客户端连接的 ...

  7. RSA非对称加密Java实现

    原文 加密基础方法类 import java.security.MessageDigest; import sun.misc.BASE64Decoder; import sun.misc.BASE64 ...

  8. [转载]java中import作用详解

    [转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...

  9. java ssl https 连接详解 生成证书 tomcat keystone

    java ssl https 连接详解 生成证书 我们先来了解一下什么理HTTPS 1. HTTPS概念 1)简介 HTTPS(全称:Hypertext Transfer Protocol over ...

随机推荐

  1. webpack打包优化

    https://www.cnblogs.com/vvjiang/p/9327903.html

  2. d3.js svg中 g 标签问题一览

    svg 中的g标签, 算是比较特殊 1 没有x y属性 2 没有width height 属性 3 不能fill 4 .... g标签基本只管分组问题, 其他功能一概不提供 要解决这些问题, 直接在g ...

  3. Linux操作系统df相关问题解惑

    1.df 命令无法使用解决办法 问题分析: 1.1 df命令是通过/etc/mtab文件读取已挂载文件系统的信息,因此,df命令无法使用的原因的在于/etc/mtab文件被损坏或者丢失. 查看 mor ...

  4. 安装sklearn_简练解决

    安装sklearn_简练解决 < 关键步骤标黑 > 第一步:更新pip  python -m pip install --upgrade pip 第二步:安装 scipy 在网址http: ...

  5. sql语句order by排序问题

    根据某个字段的值排序,等于这个值的放最前面,不等的放后面 select * from [DTS_Interface] order by case when from_tag_name='木质饰条' t ...

  6. php 微信自定义分享接口

    <?php class JSSDK { private $appId; private $appSecret; public function __construct($appId, $appS ...

  7. Redis:MySQL算老几?

    原创: 码农翻身刘欣 前言:上一篇<MySQL:缓存算什么东西?>里挖了一个坑,也有很多人说没看过瘾,今天接着写,把坑填上,不过得把视角换一下,让Redis上台发言. 我知道MySQL看我 ...

  8. slot-scope

    插槽,也就是slot,是组件的一块HTML模板,这块模板显示不显示.以及怎样显示由父组件来决定. 实际上,一个slot最核心的两个问题在这里就点出来了,是显示不显示和怎样显示. 由于插槽是一块模板,所 ...

  9. Mad Libs游戏,华氏与摄氏转换

    华氏温度 与 摄氏温度的相互转换 公式:摄氏 ℃=5/9(°F-32) 华氏°F= ℃×9/5+32 # -*- coding: UTF-8 -*- num=input('输入摄氏温度:') num ...

  10. python实现bt种子 torrent转magnet

    Python实现bt转磁链  参考前人资料主要两种方式 1,利用python的bencode模块 2,安装libtorrent模块 尝试过两种方法特记录 环境:Windows系统  python 3 ...