1、概述
RSA有两个密钥,一个是公开的,称为公开密钥;一个是私密的,称为私密密钥。
特点:
公开密钥是对大众公开的,私密密钥是服务器私有的,两者不能互推得出。
用公开密钥对数据进行加密,私密密钥可解密;私密密钥对数据加密,公开密钥可解密。
速度较对称加密慢。
2、模型分析
流程分析:
1》甲方构建密钥对儿,将公钥公布给乙方,将私钥保留。
2》甲方使用私钥加密数据,然后用私钥对加密后的数据签名,发送给乙方签名以及加密后的数据;乙方使用公钥、签名来验证待解密数据是否有效,如果有效使用公钥对数据解密。
3》乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。
甲方 发送消息 到 乙方:
乙方 发送消息 到 甲方:
3、实现
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
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;
/**
* 非对称加密算法 RSA
* Java 6
*/
public class RSACoder {
//非对称加密算法
private static final String KEY_ALGORITHM = "RSA";
//私钥
private static final String PRIVATEKEY = "RSAPrivateKey";
//公钥
private static final String PUBLICKEY = "RSAPublicKey";
/**
* RSA密钥长度
* 默认是 1024
* 必须是 64的倍数
* 范围:512 - 65536
*/
private static final int KeySize = 512;
/**
* 初始化 密钥
* @return
* @throws Exception
*/
public static Map<String, Object> initKey() throws Exception{
//实例化密钥生成器
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
//初始化
keyPairGenerator.initialize(KeySize);
//获取密钥对
KeyPair keyPair = keyPairGenerator.generateKeyPair();
//获取私钥
PrivateKey privateKey = keyPair.getPrivate();
//获取公钥
PublicKey publicKey = keyPair.getPublic();
Map<String, Object> map = new HashMap<String, Object>();
map.put(PRIVATEKEY, privateKey);
map.put(PUBLICKEY, publicKey);
return map;
}
/**
* 取得公钥
* @return
*/
public static byte[] getPublicKey(Map<String, Object> map){
PublicKey publicKey = (PublicKey) map.get(PUBLICKEY);
return publicKey.getEncoded();
}
/**
* 取得私钥
* @return
*/
public static byte[] getPrivateKey(Map<String, Object> map){
PrivateKey privateKey = (PrivateKey) map.get(PRIVATEKEY);
return privateKey.getEncoded();
}
/***
* 私钥加密
* @param data 需要加密数据
* @param key 私钥
* @return
*/
public static String encryptByPrivateKey(byte[] data,byte[] key) throws Exception{
// 取得私钥
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
// 对数据进行加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
byte[] encry = cipher.doFinal(data);
return Base64.encodeBase64String(encry);
}
/**
* 私钥解密
* @param data
* @param key
* @return
* @throws Exception
*/
public static String decryptByPrivateKey(String source,byte[] key) throws Exception{
// 还原即将 解密的 数据源
byte[] data = Base64.decodeBase64(source);
// 取得私钥
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成私钥
PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);
// 对数据进行加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, privateKey);
byte[] decry = cipher.doFinal(data);
return new String(decry);
}
/***
* 公钥加密
* @param data 需要加密数据
* @param key 公钥
* @return
*/
public static String encryptByPublicKey(byte[] data,byte[] key) throws Exception{
// 取得公钥
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成公钥
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
// 对数据进行加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encry = cipher.doFinal(data);
return Base64.encodeBase64String(encry);
}
/**
* 公钥解密
* @param data
* @param key
* @return
* @throws Exception
*/
public static String decryptByPublicKey(String source,byte[] key) throws Exception{
// 还原即将 解密的 数据源
byte[] data = Base64.decodeBase64(source);
// 取得公钥
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 生成公钥
PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);
// 对数据进行加密
Cipher cipher = Cipher.getInstance(KEY_ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, publicKey);
byte[] decry = cipher.doFinal(data);
return new String(decry);
}
public static void main(String[] args) throws Exception {
Map<String, Object> keyMap = initKey();
byte[] privateKey = getPrivateKey(keyMap);
byte[] publicKey = getPublicKey(keyMap);
System.out.println("获取的私钥:" + Base64.encodeBase64String(privateKey));
System.out.println("获取的公钥:" + Base64.encodeBase64String(publicKey));
/***console:
* 获取的私钥:MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAj+ovH4MVA1CFnxcQKfESQ/n6tsMcGs2zjrO/6tlatPGHvfiV9GcjqyR1yjfn22AvJumz7/yIUE1KF5O
* fnbj8bQIDAQABAkEAiE9t1tEXhA4uoeL8Yl19yXjqqVTgN9sB6XYDn3PD4IFA0hq8feyWs/RwD+z5Qoy6EsQ6QD3MBzxYAxGto1T5WQIhAMor1tGl3qQGe0cZAhT38j/RK0Q+8Ce
* NhNDEg2KjTsQvAiEAtjuJIYzYEykOfKlBM5FX3C9F4Ek+iuN2BQKvkO7B9iMCIC5eRaPJzjmCfw28b5zNjVMTrz+0y7HWpGqZV6Ts3ajjAiBcEZJD8BvO+mRGWWEGw7znEr80BO1
* jUG51M5kuGWLHjwIhAKarxOajdjXLoGp3WffU9wKmVHKpJD5tQWGd/l5NMIry
获取的公钥:MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAI/qLx+DFQNQhZ8XECnxEkP5+rbDHBrNs46zv+rZWrTxh734lfRnI6skdco359tgLybps+/8iFBNSheTn524/G0CAwEAAQ==
*/
System.out.println("-----------RSA 加解密测试 私钥加密/公钥解密-------------------------");
String source = "RSA加密算法测试";
String encry = encryptByPrivateKey(source.getBytes("utf-8"), privateKey);
System.out.println(source +"->私钥加密后:" + encry);
String decry = decryptByPublicKey(encry, publicKey);
System.out.println(source +"->公钥解密后:" + decry);
/**console结果:
* -----------RSA 加解密测试 私钥加密/公钥解密-------------------------
RSA加密算法测试->私钥加密后:hMouobdtCzi7O33fTfR/QVK9v0n3FdzTRoMGWsoJVz5njsmv6Sz9d8u7mkFDUcukEBArBJvpF+N45odoTA4hMw==
RSA加密算法测试->公钥解密后:RSA加密算法测试
*/
System.out.println("------------RSA 加解密测试 公钥加密/私钥解密----------------------");
source = "RSA加密算法测试 - 公钥加密,私钥解密";
encry = encryptByPublicKey(source.getBytes("utf-8"), publicKey);
System.out.println(source +"->公钥加密后:" + encry);
decry = decryptByPrivateKey(encry, privateKey);
System.out.println(source +"->私钥解密后:" + decry);
/**console:
* ------------RSA 加解密测试 公钥加密/私钥解密----------------------
RSA加密算法测试 - 公钥加密,私钥解密->公钥加密后:f2hDzNp+lxV8jAV0Ek393i8hS2A36tBJDH9JwPhwrTTkBdtao8VzJhL15zu4RS8rtjaw+/AWpOxoQNKyN2EaXA==
RSA加密算法测试 - 公钥加密,私钥解密->私钥解密后:RSA加密算法测试 - 公钥加密,私钥解密
*/
}
}