学习JAVA中RSA算法实现
Posted 专注着
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习JAVA中RSA算法实现相关的知识,希望对你有一定的参考价值。
package org.java.se.security.rsa;
import java.io.IOException;
import java.security.InvalidKeyException;
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.SignatureException;
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.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.java.se.security.base64.Base64;
import org.junit.Before;
import org.junit.Test;
/**
* RSA加密解密和签名的实现
* @author xianglj
*/
public class RSACodec
/**
* RSA的签名算法
*/
private static final String ALGORITHM_RSA = "RSA";
/**
* 签名算法
*/
private static final String ALGORITHM_SIGNATURE = "MD5withRSA";
private static final String RSA_PRIVATE_KEY = "RSAPrivateKey";
private static final String RSA_PUBLIC_KEY = "RSAPublicKey";
/**
* 生成私钥和私钥对
* @return
* @throws NoSuchAlgorithmException
*/
public static Map<String, Key> generateKeyPair() throws NoSuchAlgorithmException
KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGORITHM_RSA);
KeyPair keyPair = generator.generateKeyPair();
PublicKey pk = keyPair.getPublic();
PrivateKey prK = keyPair.getPrivate();
Map<String, Key> keyMap = new HashMap<String, Key>();
keyMap.put(RSA_PRIVATE_KEY, prK);
keyMap.put(RSA_PUBLIC_KEY, pk);
return keyMap;
/**
* 签名。运用私钥进行签名
* @param data 需要加密的数据
* @param secretKey 私钥字符串-base64加密字符串
* @return
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
* @throws SignatureException
*/
public static String sign(byte[] data, String secretKey) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException
byte[] bytes = Base64.decript(secretKey);
//获取私钥
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
PrivateKey pk = keyFactory.generatePrivate(keySpec);
//进行签名
Signature signnature = Signature.getInstance(ALGORITHM_SIGNATURE);
signnature.initSign(pk);
signnature.update(data);
return Base64.encript(signnature.sign());
/**
* 验证签名
* @return
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
* @throws SignatureException
*/
public static boolean verify(byte[] data, String publicKey, String sign) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException, SignatureException
//生成公钥
byte[] bytes = Base64.decript(publicKey);
//构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
PublicKey pk = keyFactory.generatePublic(keySpec);
//验证签名
Signature signature = Signature.getInstance(ALGORITHM_SIGNATURE);
signature.initVerify(pk);
signature.update(data);
return signature.verify(Base64.decript(sign));
/**
* 采用私钥对数据进行加密
*
* @param data
* @param privateKey
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static String encriptByPrivateKey(byte[] data, String privateKey)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
//获取privateKey
byte[] bytes = Base64.decript(privateKey);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(bytes);
KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM_RSA);
PrivateKey pk = keyFactory.generatePrivate(keySpec);
//对数据进行加密
Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
cipher.init(Cipher.ENCRYPT_MODE, pk);
cipher.update(data);
return Base64.encript(cipher.doFinal());
/**
* 通过公钥加密
*
* @param data
* @param publicKey
* @return
* @throws IOException
* @throws InvalidKeySpecException
* @throws NoSuchAlgorithmException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static String encriptByPublicKey(byte[] data, String publicKey) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
byte[] bytes = Base64.decript(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(bytes);
PublicKey pk = KeyFactory.getInstance(ALGORITHM_RSA).generatePublic(keySpec);
Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
cipher.init(Cipher.ENCRYPT_MODE, pk);
cipher.update(data);
return Base64.encript(cipher.doFinal());
/**
* 使用私钥进行解密。
* @param data 采用PublicKey进行加密的字节数组
* @param privateKey 私钥的Base64字符串。
* @return 采用私钥解密后的byte数组
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static byte[] decriptByPrivateKey(byte[] data, String privateKey) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
//获取私钥
byte[] pkBytes = Base64.decript(privateKey);
//构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(pkBytes);
PrivateKey pk = KeyFactory.getInstance(ALGORITHM_RSA).generatePrivate(keySpec);
//进行解密
Cipher cipher = Cipher.getInstance(ALGORITHM_RSA); //构建Cipher对象
//设置cipher的模式
cipher.init(Cipher.DECRYPT_MODE, pk);
//解密数据
cipher.update(data);
return cipher.doFinal();
/**
* 根据公钥进行解密
*
* @param data 经过私钥加密的字节数组
* @param publicKey 公钥字符串
* @return 解密后的字节数组
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws NoSuchPaddingException
* @throws InvalidKeyException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
*/
public static byte[] decriptByPublicKey(byte[] data, String publicKey) throws IOException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException
//获取公钥
byte[] pkBytes = Base64.decript(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(pkBytes);
PublicKey pk = KeyFactory.getInstance(ALGORITHM_RSA).generatePublic(keySpec);
Cipher cipher = Cipher.getInstance(ALGORITHM_RSA);
cipher.init(Cipher.DECRYPT_MODE, pk);
cipher.update(data);
return cipher.doFinal();
/**
* 获取公钥字符串
*/
public static String getPublicKey()
Key publicKey = keyMap.get(RSA_PUBLIC_KEY);
return Base64.encript(publicKey.getEncoded());
/**
* 获取私钥
* @return
*/
public static String getPrivateKey()
Key privateKey = keyMap.get(RSA_PRIVATE_KEY);
return Base64.encript(privateKey.getEncoded());
private static Map<String, Key> keyMap ;
@Before
public void setUp() throws NoSuchAlgorithmException
keyMap = generateKeyPair();
@Test
public void testSign() throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, SignatureException, IOException
String privateKey = getPrivateKey();
String publicKey = getPublicKey();
System.out.println("私钥:" + privateKey);
System.out.println("公钥:" + publicKey);
//需要签名的数据
String data = "这个数据需要签名";
String signData = sign(data.getBytes(), privateKey);
System.out.println("签名的数据为:" + signData);
//验证签名
boolean isSuc = verify(data.getBytes(), publicKey, signData);
System.out.println("签名是否成功:" + isSuc);
/**
* 测试使用公钥加密,私钥解密
* @throws IOException
* @throws BadPaddingException
* @throws IllegalBlockSizeException
* @throws NoSuchPaddingException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws InvalidKeyException
*/
@Test
public void testCript() throws InvalidKeyException, InvalidKeySpecException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, IOException
String privateKey = getPrivateKey();
String publicKey = getPublicKey();
//设置需要加密的字符串
String str = "我将要被公钥加密,私钥解密哦。。。。";
System.out.println("明文为:\\r\\n" + str);
//利用公钥加密
String encriptStr = encriptByPublicKey(str.getBytes(), publicKey);
System.out.println("采用公钥加密后的密文为:\\r\\n" + encriptStr);
//采用私钥解密
byte[] pkBytes = decriptByPrivateKey(Base64.decript(encriptStr), privateKey);
String decriptStr = new String(pkBytes);
System.out.println("采用公钥解密后的明文为:\\r\\n" + decriptStr);
//比较
System.out.println("明文和密文是否一致:\\r\\n" + (str.equals(decriptStr)));
/**
* 测试采用私钥加密,公钥解密
*
* @throws InvalidKeyException
* @throws NoSuchAlgorithmException
* @throws InvalidKeySpecException
* @throws NoSuchPaddingException
* @throws IllegalBlockSizeException
* @throws BadPaddingException
* @throws IOException
*/
@Test
public void encriptTest() throws InvalidKeyException, NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, IOException
String privateKey = getPrivateKey();
String publicKey = getPublicKey();
//设置需要加密的字符串
String str = "我将要被私钥加密,用公钥解密....";
System.out.println("明文:" + str);
//利用私钥加密
String ecriptStr = encriptByPrivateKey(str.getBytes(), privateKey);
System.out.println("利用公钥加密后的密文为:" + ecriptStr);
//利用公钥解密
byte[] pkBytes = decriptByPublicKey(Base64.decript(ecriptStr), publicKey);
String decriptStr = new String(pkBytes);
System.out.println("解密后的明文为:" + decriptStr);
//比较
System.out.println("是否一致:" + (str.equals(decriptStr)));
RSA为非对称加密算法,主要实现步骤:
1. 生成密钥对。私钥和公钥。公钥可以对外公布,或者发布于客户端使用。
2. RSA的加密和解密,都需要密钥的参与。如果采用PublicKey进行加密,则需要对应的 PrivateKey 进行解密。如果采用PrivateKey加密,则需要PublicKey进行解密。因此为了数据的安全性,需要妥善保管密钥
以上是关于学习JAVA中RSA算法实现的主要内容,如果未能解决你的问题,请参考以下文章