文章目录
RSA(典型非对称加密算法)
RSACoder工具类
RSACoderTest
参考资料
本系列其他文章
之前介绍了DH算法,现在我们来介绍RSA算法。
在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,由于无法计算出大数n的欧拉函数phi(N),所以不能根据PK计算出SK。百度百科
基本上所有的非对称加密都是基于数学难题(基本上无解),而RSA算法是基于大数因数分解难题。即将两个大素数相乘很容易,但是想要将相乘的结果分解为两个大素数是非常困难(几乎不可能)。
import java.security.GeneralSecurityException;
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;
/**
* RSA 编码组件
*
* @author shaozuo
* @date 2018/08/01
*/
public final class RSACoder {
public static final String ALGORITHM_NAME = "RSA";
private RSACoder() {
}
private static final int KEY_SIZE = 512;
private static final String PUBLIC_KEY = "public_key";
private static final String PRIVATE_KEY = "private_key";
/**
* 初始化公钥
*
* @return Map 密钥map
* @throws Exception
*/
public static Map initKey() throws Exception {
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM_NAME);
keyPairGenerator.initialize(KEY_SIZE);
KeyPair keyPair = keyPairGenerator.generateKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
Map keyMap = new HashMap<>();
keyMap.put(PUBLIC_KEY, publicKey);
keyMap.put(PRIVATE_KEY, privateKey);
return keyMap;
}
public static byte[] getPrivateKey(Map keyMap) {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return key.getEncoded();
}
public static byte[] getPublicKey(Map keyMap) {
Key key = (Key) keyMap.get(PUBLIC_KEY);
return key.getEncoded();
}
/**
* 使用公钥加密数据
*
* @param data
* 待加密数据
* @param encodedPublicKey
* 公钥
* @return
* @throws GeneralSecurityException
*/
public static byte[] encyptByPublicKey(byte[] data, byte[] encodedPublicKey)
throws GeneralSecurityException {
X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(encodedPublicKey);
KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME);
PublicKey publicKey = factory.generatePublic(encodedKeySpec);
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 使用私钥加密数据
*
* @param data
* 待加密数据
* @param encodedPublicKey
* 私钥
* @return
* @throws GeneralSecurityException
*/
public static byte[] encyptByPrivateKey(byte[] data, byte[] encodedPrivateKey)
throws GeneralSecurityException {
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME);
PrivateKey privateKey = factory.generatePrivate(encodedKeySpec);
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
/**
* 使用公钥解密数据
*
* @param data
* 待解密数据
* @param encodedPublicKey
* 公钥
* @return
* @throws GeneralSecurityException
*/
public static byte[] decyptByPublicKey(byte[] data, byte[] encodedPublicKey)
throws GeneralSecurityException {
X509EncodedKeySpec encodedKeySpec = new X509EncodedKeySpec(encodedPublicKey);
KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME);
PublicKey publicKey = factory.generatePublic(encodedKeySpec);
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}
/**
* 使用私钥解密数据
*
* @param data
* 待解密数据
* @param encodedPublicKey
* 私钥
* @return
* @throws GeneralSecurityException
*/
public static byte[] decyptByPrivateKey(byte[] data, byte[] encodedPrivateKey)
throws GeneralSecurityException {
PKCS8EncodedKeySpec encodedKeySpec = new PKCS8EncodedKeySpec(encodedPrivateKey);
KeyFactory factory = KeyFactory.getInstance(ALGORITHM_NAME);
PrivateKey privateKey = factory.generatePrivate(encodedKeySpec);
Cipher cipher = Cipher.getInstance(factory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}
}
import static org.junit.Assert.assertEquals;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.junit.Before;
import org.junit.Test;
public class RSACoderTest {
// 公钥
private byte[] publicKey;
// 私钥
private byte[] privateKey;
String rawStrForPri = "RSA 私钥加密-公钥解密";
String rawStrForPub = "RSA 公钥加密-私钥解密";
@Before
public final void initKey() throws Exception {
Map keyMap = RSACoder.initKey();
publicKey = RSACoder.getPublicKey(keyMap);
privateKey = RSACoder.getPrivateKey(keyMap);
System.out.println("公钥: " + Base64.encodeBase64String(publicKey));
System.out.println("私钥: " + Base64.encodeBase64String(privateKey));
}
@Test
public void test() throws Exception {
System.out.println("待加密数据:" + rawStrForPri);
System.out.println("原文:" + rawStrForPri);
byte[] encodeData = RSACoder.encyptByPrivateKey(rawStrForPri.getBytes(), privateKey);
System.out.println("加密数据: " + Base64.encodeBase64String(encodeData));
byte[] decodeData = RSACoder.decyptByPublicKey(encodeData, publicKey);
String output = new String(decodeData);
System.out.println("解密数据:" + output);
assertEquals(rawStrForPri, output);
// -----公钥加密
System.out.println("待加密数据:" + rawStrForPub);
System.out.println("原文:" + rawStrForPub);
encodeData = RSACoder.encyptByPublicKey(rawStrForPub.getBytes(), publicKey);
System.out.println("加密数据: " + Base64.encodeBase64String(encodeData));
decodeData = RSACoder.decyptByPrivateKey(encodeData, privateKey);
output = new String(decodeData);
System.out.println("解密数据:" + output);
assertEquals(rawStrForPub, output);
}
}
关于本章内容,参考了一下书籍和文章
密码技术学习系列文章