基本概念
RSA加密算法:RSA加密算法是一种非对称加密算法。在公开密钥加密和电子商业中RSA被广泛使用。RSA是1977年由罗纳德·李维斯特(Ron Rivest)、阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的。当时他们三人都在麻省理工学院工作。RSA就是他们三人姓氏开头字母拼在一起组成的。
RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数组合成私钥。公钥是可发布的供任何人使用,私钥则为自己所有,供解密之用。
解密者拥有私钥,并且将由私钥计算生成的公钥发布给加密者。加密都使用公钥进行加密,并将密文发送到解密者,解密者用私钥解密将密文解码为明文。
API
https://docs.oracle.com/javase/7/docs/api/index.html
X509EncodedKeySpec:
- 该类表示公钥的ASN.1编码,根据ASN.1类型
SubjectPublicKeyInfo
进行编码。SubjectPublicKeyInfo
语法在X.509标准中定义如下:SubjectPublicKeyInfo ::= SEQUENCE { algorithm AlgorithmIdentifier, subjectPublicKey BIT STRING }
构造方法:
X509EncodedKeySpec(byte[] encodedKey)
用给定的编码密钥创建一个新的X509EncodedKeySpec。
参数
encodedKey
- 假定按照X.509标准编码的密钥。 复制数组的内容以防止后续修改。异常
NullPointerException
- 如果encodedKey
为空。
PKCS8EncodedKeySpec:
- 该类代表私有密钥的ASN.1编码,根据ASN.1类型
PrivateKeyInfo
进行编码。PrivateKeyInfo
语法在PKCS#8标准中定义如下:PrivateKeyInfo ::= SEQUENCE { version Version, privateKeyAlgorithm PrivateKeyAlgorithmIdentifier, privateKey PrivateKey, attributes [0] IMPLICIT Attributes OPTIONAL } Version ::= INTEGER PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier PrivateKey ::= OCTET STRING Attributes ::= SET OF Attribute
构造方法:
PKCS8EncodedKeySpec(byte[] encodedKey)
使用给定的编码密钥创建一个新的PKCS8EncodedKeySpec。
RSAPrivateKeySpec:
- 此类指定一个RSA私钥。
构造方法:
RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent)
创建一个新的RSAPrivateKeySpec。
参数
modulus
- 模数
privateExponent
- 私人指数
RSAPublicKeySpec:
- 此类指定一个RSA公钥。
构造方法:
RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent)
创建一个新的RSAPublicKeySpec。
参数
modulus
- 模数
publicExponent
- 公众指数
DEMO
package cn.aizichan.utils.digest;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
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;
import javax.crypto.Cipher;
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="xiaoxiaorenzhe";
//私钥
private static final String PRIVATE_KEY="dadapangzi";
/**
* 初始化密钥对
* @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();
System.out.println("系数:"+publicKey.getModulus()+" 加密指数:"+publicKey.getPublicExponent());
//甲方私钥
RSAPrivateKey privateKey=(RSAPrivateKey) keyPair.getPrivate();
System.out.println("系数:"+privateKey.getModulus()+"解密指数:"+privateKey.getPrivateExponent());
//将密钥存储在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[] publicKey = b;
//私钥
byte[] privateKey=RSACoder.getPrivateKey(keyMap);
System.out.println("公钥:"+Base64.encode(publicKey));
System.out.println("私钥:"+Base64.encode(privateKey));
System.out.println("================密钥对构造完毕,甲方将公钥公布给乙方,开始进行加密数据的传输=============");
String str="aattaggcctegthththfef/aat.mp4";
System.out.println("===========甲方向乙方发送加密数据==============");
System.out.println("原文:"+str);
//甲方进行数据的加密
byte[] code1=RSACoder.encryptByPublicKey(str.getBytes(), publicKey);
System.out.println("甲方 使用乙方公钥加密后的数据:"+Base64.encode(code1));
System.out.println("===========乙方使用甲方提供的公钥对数据进行解密==============");
//乙方进行数据的解密
//byte[] decode1=RSACoder.decryptByPublicKey(code1, publicKey);
byte[] decode1=RSACoder.decryptByPrivateKey(code1, privateKey);
System.out.println("乙方解密后的数据:"+new String(decode1)+"");
System.out.println("===========反向进行操作,乙方向甲方发送数据==============");
str="乙方向甲方发送数据RSA算法";
System.out.println("原文:"+str);
//乙方使用公钥对数据进行加密
byte[] code2=RSACoder.encryptByPublicKey(str.getBytes(), publicKey);
System.out.println("===========乙方使用公钥对数据进行加密==============");
System.out.println("加密后的数据:"+Base64.encode(code2));
System.out.println("=============乙方将数据传送给甲方======================");
System.out.println("===========甲方使用私钥对数据进行解密==============");
//甲方使用私钥对数据进行解密
byte[] decode2=RSACoder.decryptByPrivateKey(code2, privateKey);
System.out.println("甲方解密后的数据:"+new String(decode2));
}
}
参考文章
https://www.iteye.com/topic/1148471