RSA是一种非对称加密算法,使用RSA前先生成一对公钥和私钥。

使用公钥加密的数据可以用私钥解密,同样私钥加密的数据也可以用公钥解密,

不同之处在于,私钥加密数据的同时还可以生成一组签名,签名是用来验证数据是否在传输过程中有变动的,使用公钥、签名、以及公钥加密后的数据,就可以验证是否有变动,当然也可以不验证。

代码示例如下,两个main方法:main和main1。加密解密都是针对byte数组的,考虑到我们实际使用的时候大部分场景应该是用字符串来传递数据,所以演示代码中频繁的将byte数组转化为字符串,有些byte数组不是从字符串直接转化来的,直接通过new String的方式转字符串会出现乱码,所以用到了Base64来解决这一问题。

另外,演示代码为了方便看到全过程,基本上没有抽出方法,实际使用的时候建议重构一下。

说明就到此为止,代码如下:

 package testEncrypt;

 import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
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.Cipher; import org.apache.commons.codec.binary.Base64; /**
*
* @ClassName: TestRsaEncrypt
* @Description: TODO
* @author: liuyx
* @date: 2016年4月28日上午10:20:59
*/
public class TestRsaEncrypt {
public static final String KEY_ALGORITHM = "RSA";
private static final String PUBLIC_KEY = "RSAPublicKey";
private static final String PRIVATE_KEY = "RSAPrivateKey";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";
private static KeyFactory keyFactory = null;
static {
try {
keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//公钥加密 私钥解密
public static void main(String[] args) throws Exception {
//生成密钥对 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(512); KeyPair keyPair = keyPairGen.generateKeyPair(); // 公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey); String publicKeyStr = getBase64KeyEncodeStrFromKey(publicKey);
String privateKeyStr = getBase64KeyEncodeStrFromKey(privateKey);
System.out.println("公钥:"+publicKeyStr);
System.out.println("私钥:"+privateKeyStr); //数据加密过程演示
System.out.println("公钥加密——私钥解密"); //要加密的数据
String dataStr = "abcdefghhhhhhhopqrst";
System.out.println("要加密的数据:"+dataStr);
byte[] data = dataStr.getBytes(); // 对公钥解密
Key decodePublicKey = getPublicKeyFromBase64KeyEncodeStr(publicKeyStr); // 对数据加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, decodePublicKey);
byte[] encodedData = cipher.doFinal(data);
String encodedDataStr = Base64.encodeBase64String(encodedData);
System.out.println("公钥加密后的数据:"+encodedDataStr); //对私钥解密
Key decodePrivateKey = getPrivateKeyFromBase64KeyEncodeStr(privateKeyStr);
cipher.init(Cipher.DECRYPT_MODE, decodePrivateKey);
encodedData = Base64.decodeBase64(encodedDataStr);
byte[] decodedData = cipher.doFinal(encodedData);
String decodedDataStr = new String(decodedData);
System.out.println("私钥解密后的数据:"+decodedDataStr);
} //私钥加密 公钥解密,附带签名验证过程
public static void main1(String[] args) throws Exception {
//生成密钥对 KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(512); KeyPair keyPair = keyPairGen.generateKeyPair(); // 公钥
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic(); // 私钥
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate(); Map<String, Object> keyMap = new HashMap<String, Object>(2); keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey); String publicKeyStr = getBase64KeyEncodeStrFromKey(publicKey);
String privateKeyStr = getBase64KeyEncodeStrFromKey(privateKey);
System.out.println("公钥:"+publicKeyStr);
System.out.println("私钥:"+privateKeyStr); //数据加密过程演示
System.out.println("私钥加密——公钥解密"); //要加密的数据
String dataStr = "abcdefghhhhhhhopqrst1";
System.out.println("要加密的数据:"+dataStr);
byte[] data = dataStr.getBytes(); //对私钥解密
Key decodePrivateKey = getPrivateKeyFromBase64KeyEncodeStr(privateKeyStr);
//对公钥解密
Key decodePublicKey = getPublicKeyFromBase64KeyEncodeStr(publicKeyStr); // 对数据加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, decodePrivateKey);
byte[] encodedData = cipher.doFinal(data); //插曲,加密后的数据+私钥,生成签名,验证签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign((PrivateKey)decodePrivateKey); //用的是私钥
signature.update(encodedData); //用的是加密后的数据字节数组 //取得签名
String sign = Base64.encodeBase64String((signature.sign())); //初始化验证签名
signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify((PublicKey )decodePublicKey); //用的是公钥
signature.update(encodedData); //用的是加密后的数据字节数组 //实际的验证过程,获取验证结果
boolean ret = signature.verify(Base64.decodeBase64(sign));
System.out.println("验证结果:"+ret);
//插曲结束 String encodedDataStr = Base64.encodeBase64String(encodedData);
System.out.println("私钥加密后的数据:"+encodedDataStr); cipher.init(Cipher.DECRYPT_MODE, decodePublicKey);
encodedData = Base64.decodeBase64(encodedDataStr);
byte[] decodedData = cipher.doFinal(encodedData);
String decodedDataStr = new String(decodedData);
System.out.println("公钥解密后的数据:"+decodedDataStr); } /*
* 获取key的base64加密后的字符串
*/
private static String getBase64KeyEncodeStrFromKey(Key key) {
return Base64.encodeBase64String(key.getEncoded());
} /*
* 获取base64加密后的字符串的原始公钥
*/
private static Key getPublicKeyFromBase64KeyEncodeStr(String keyStr) {
byte[] keyBytes = Base64.decodeBase64(keyStr);
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
Key publicKey = null;
try {
publicKey = keyFactory.generatePublic(x509KeySpec);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return publicKey;
} private static Key getPrivateKeyFromBase64KeyEncodeStr(String keyStr) {
byte[] keyBytes = Base64.decodeBase64(keyStr);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes); Key privateKey=null;
try {
privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
} catch (InvalidKeySpecException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return privateKey;
}
}

加密算法使用(五):RSA使用全过程的更多相关文章

  1. 公钥加密算法那些事 | RSA 与 ECC 系统对比

    一.背景 据记载,公元前 400 年,古希腊人发明了置换密码.1881 年世界上的第一个电话保密专利出现.在第二次世界大战期间,德国军方启用「恩尼格玛」密码机,密码学在战争中起着非常重要的作用. 随着 ...

  2. 加密算法—MD5、RSA、DES

    最近因为要做一个加密的功能,简单了解了一下加密算法,现在比较常用的有三个加密算法MD5加密算法.RSA加密算法.DES加密算法.       MD5加密算法     定义:MD5算法是将任意长度的“字 ...

  3. 3个著名加密算法(MD5、RSA、DES)的解析

    MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2.MD3和MD4发展而来.    M ...

  4. 加密算法 DES 3DES RSA AES 简介

    数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为[密文],使其只能在输入相应的[密钥]之后才能显示出本来内容,通过这样的途径来达到保护数据不被非法人 ...

  5. [转]3个著名加密算法(MD5、RSA、DES)的解析

    MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2.MD3和MD4发展而来.     ...

  6. java加密算法AES与RSA

    1.commons-codec使用 commons-codes 常用工具类:DigestUtils,Base64,Hex 1.1 md5 String text = "hello,md5&q ...

  7. [加密算法]为什么说RSA难以被破解

    RSA算法运用了数学“两个大的质数相乘,难以在短时间内将其因式分解”的这么一套看似简单事实上真的是很困难的一个数学难题...... 以前也接触过RSA加密算法,感觉这个东西太神秘了,是数学家的事,和我 ...

  8. 加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用(转载)

    加密技术通常分为两大类:"对称式"和"非对称式". 对称性加密算法:对称式加密就是加密和解密使用同一个密钥.信息接收双方都需事先知道密匙和加解密算法且其密匙是相 ...

  9. 加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用

    加密技术通常分为两大类:"对称式"和"非对称式". 对称性加密算法:对称式加密就是加密和解密使用同一个密钥.信息接收双方都需事先知道密匙和加解密算法且其密匙是相 ...

随机推荐

  1. ios开发随笔第一篇-button,label按钮的一些属性的使用

    我用的是纯代码方式,喜欢用storyboard开发的其实也很爽了; 首先谈谈button,ios中新建button这个对象一般接触的都明白,UIButton *button名=[ UIButton a ...

  2. iOS多线程-01-pthread与NSTread

    简介 恰当的使用多线程编程可以提供任务的执行效率和系统资源的利用率 多线程是为了提高资源利用率,和应用程序的响应速度,多个线程共享应用资源 每个应用程序都有一个主线程,通常用来做UI界面刷新等 比较耗 ...

  3. C语言错误之--初始值(低级错误)

    今天犯了一个低级错误,虽然低级,但是也不能忽视,一个低级错误以后可能小则浪费时间和精力,大则酿成整个app的项目bug.    

  4. Reverse反转算法+斐波那契数列递归+Reverse反转单链表算法--C++实现

    Reverse反转算法 #include <iostream> using namespace std; //交换的函数 void replaced(int &a,int & ...

  5. centos创建监控宝采集器及添加插件任务

    官方的说明文档很不详细操作也有点小问题,故把操作记录如下. 操作系统环境: centos 5.8 python 2.4.3 创建采集器等操作这里就不说了,见官方文档:http://blog.jiank ...

  6. MyEclipse Workspace 项目文件 .project .classpath .mymetadata解析

    <!-- .classpath文件 --> <?xml version="1.0" encoding="UTF-8"?> <cla ...

  7. MS SqlServer学习笔记(索引)

    1.索引分类 MS SqlServer提供了两种索引:聚集索引和非聚集索引: 聚集索引是将数据按照索引的顺序存放 非聚集索引是将索引和数据分离存放,通过指针将二者联系到一起. 因为两种索引对比: 使用 ...

  8. ProjectManager Alpha8 - 项目管理器,管理起开发中的项目很方便

    话不多说= = 放几张图了: 文件下载: 32位下载:Package_ProjectManager-1.13.12.exe 64位下载:Package_ProjectManager_x64-1.13. ...

  9. 最长公共子序列模板(LCS)和LICS模板

    递归式: 实例图解: 代码: #include<stdio.h> #include<string.h> ; int dp[N][N],f[N][N]; char a[N],b[ ...

  10. RabbitMQ 一二事(2) - 工作队列使用

    上篇文章讲了简单队列的使用,这其实就是RMQ给的demo,实际并没有什么用 本篇讲讲工作模式队列,也称之为任务队列 一个生产者发布了多条消息,消费者A可以接受消息,接受消息后该消息就消除,消费者B可以 ...