加密算法使用(五):RSA使用全过程
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使用全过程的更多相关文章
- 公钥加密算法那些事 | RSA 与 ECC 系统对比
一.背景 据记载,公元前 400 年,古希腊人发明了置换密码.1881 年世界上的第一个电话保密专利出现.在第二次世界大战期间,德国军方启用「恩尼格玛」密码机,密码学在战争中起着非常重要的作用. 随着 ...
- 加密算法—MD5、RSA、DES
最近因为要做一个加密的功能,简单了解了一下加密算法,现在比较常用的有三个加密算法MD5加密算法.RSA加密算法.DES加密算法. MD5加密算法 定义:MD5算法是将任意长度的“字 ...
- 3个著名加密算法(MD5、RSA、DES)的解析
MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2.MD3和MD4发展而来. M ...
- 加密算法 DES 3DES RSA AES 简介
数据加密的基本过程就是对原来为明文的文件或数据按某种算法进行处理,使其成为不可读的一段代码,通常称为[密文],使其只能在输入相应的[密钥]之后才能显示出本来内容,通过这样的途径来达到保护数据不被非法人 ...
- [转]3个著名加密算法(MD5、RSA、DES)的解析
MD5的全称是Message-Digest Algorithm 5,在90年代初由MIT的计算机科学实验室和RSA Data Security Inc发明,经MD2.MD3和MD4发展而来. ...
- java加密算法AES与RSA
1.commons-codec使用 commons-codes 常用工具类:DigestUtils,Base64,Hex 1.1 md5 String text = "hello,md5&q ...
- [加密算法]为什么说RSA难以被破解
RSA算法运用了数学“两个大的质数相乘,难以在短时间内将其因式分解”的这么一套看似简单事实上真的是很困难的一个数学难题...... 以前也接触过RSA加密算法,感觉这个东西太神秘了,是数学家的事,和我 ...
- 加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用(转载)
加密技术通常分为两大类:"对称式"和"非对称式". 对称性加密算法:对称式加密就是加密和解密使用同一个密钥.信息接收双方都需事先知道密匙和加解密算法且其密匙是相 ...
- 加密算法(DES,AES,RSA,MD5,SHA1,Base64)比较和项目应用
加密技术通常分为两大类:"对称式"和"非对称式". 对称性加密算法:对称式加密就是加密和解密使用同一个密钥.信息接收双方都需事先知道密匙和加解密算法且其密匙是相 ...
随机推荐
- IOS中把字符串加密/IOS中怎么样MD5加密/IOS中NSString分类的实现
看完过后,你会学到: 1学习IOS开发中的分类实现, 2以及类方法的书写, 3以及字符串的MD5加密/解密. ---------------------------wolfhous---------- ...
- C99标准的新特性
C语言标准的发展 C语言的发展历史大致上分为4个阶段:Old Style C.C89.C99和C11. C89是最早的C语言规范,于1989年提出,1990年先由ANSI(美国国家标准委员会,Amer ...
- 【读书笔记】iOS-Xcode知识-多线程
一,Xcode使用的调试器是GDB.GDB是GNU项目的一部分,它可以在很多不同的平台上使用.如果你愿意,可以通过命令行来运行它.GDB有着完善的文档系统,尽管它的文档有些难于理解并且网络上流传着好几 ...
- 网络开始---多线程---NSThread-02-线程状态(了解)(三)
#import "HMViewController.h" @interface HMViewController () @property (nonatomic, strong) ...
- iOS 正则表达式判断邮箱、身份证..是否正确
//邮箱 + (BOOL) validateEmail:(NSString *)email { NSString *emailRegex = @"[A-Z0-9a-z._%+-]+@[A-Z ...
- Java集合 之 List 集合
1.什么是Lsit集合? List集合是一种元素有序的,可重复的集合,集合中每个元素都有自己的元素索引.List集合允许可重复的元素,可以通过索引来访问指定位置的元素. 2.Java8改进的List接 ...
- 解决Junit单元测试 找不到类 ----指定Java Build Path
做junit 单元测试时,发现怎么执行都是以前编译过得代码. 最后找到原因了, src/test/java 编译完的.class路径是 Default output folder Default ou ...
- css中font-family的中文字体
说到css中的font-family,相信很多朋友经常用,但不知道当你遇到引用中文字体的时候你会怎么写?最近特别关注了下,发现最常用的基本有三种类型: 1.直接中文: 2.英文形式: 3.unicod ...
- 中国IT新闻现状
作为一个从业人员,对中国的IT新闻是很有看法的,在这里想说些脏话——要是不让我说脏话,那我就不说话了.如果有心理不适者,请点X离开. 一. 传传传传传,传尼玛B 不知道读者对一些传闻式的新闻有什么看法 ...
- NoSQL介绍
NoSQL(Not Only SQL),是一种非关系型数据库:说到这里,大家需要了解关系型数据库和非关系型数据库的区别,可参考:从关系型数据库到非关系型数据库. NoSQL是以key-value形式存 ...