废话不多说,直接上代码,不懂的看注释。代码如下:
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/**
* RSA加密实现
* @author hxstrive.com
*/
public class RSAEncrypt {
/**
* RSA算法允许最大加密数据块大小
*/
private static final int ENCRYPT_BLOCK_SIZE = 117;
/**
* RSA算法允许最大解密数据块大小
*/
private static final int DECRYPT_BLOCK_SIZE = 128;
/**
* 获取RSA私钥对象
* @param privateKey 私钥
* @return 返回 PrivateKey 对象
*/
private static PrivateKey getPrivateKey(String privateKey) throws Exception {
byte[] decoded = Base64.decodeBase64(privateKey);
PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decoded);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePrivate(keySpec);
}
/**
* 获取RSA公钥对象
* @param publicKey 公钥
* @return 返回 PublicKey 对象
*/
private static PublicKey getPublicKey(String publicKey) throws Exception {
byte[] decoded = Base64.decodeBase64(publicKey);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decoded);
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
return keyFactory.generatePublic(keySpec);
}
/**
* 私钥加密
* @param bytes 待加密字节数组
* @param privateKey 私钥
* @return 返回加密后的字节数组
*/
public static byte[] encrypt(final byte[] bytes, final String privateKey) throws Exception {
if(null == bytes || bytes.length <= 0) {
throw new RuntimeException("待加密字节数组不能为空");
}
if(StringUtils.isBlank(privateKey)) {
throw new RuntimeException("私钥不能为空");
}
PrivateKey privateKeyObj = getPrivateKey(privateKey);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, privateKeyObj);
// 开始加密
// 暂存所有已加密字节,一起返回
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
byte[] tmpBytes = new byte[ENCRYPT_BLOCK_SIZE];
int len;
while((len = inputStream.read(tmpBytes)) != -1) {
if(len != ENCRYPT_BLOCK_SIZE) { // 如果加密数据不够 117 字节
byte[] buffer = new byte[len];
System.arraycopy(tmpBytes, 0, buffer, 0, len);
outputStream.write(cipher.doFinal(buffer));
} else {
outputStream.write(cipher.doFinal(tmpBytes));
}
}
outputStream.flush();
return outputStream.toByteArray();
}
/**
* 对给定的字符串进行加密,加密成功后使用Base64返回加密结果
* @param data 待加密字符串,使用 UTF-8 编码
* @param privateKey 私钥
* @return 返回使用 Base64 加密后的字符串
*/
public static String encrypt(final String data, final String privateKey) throws Exception {
return Base64.encodeBase64String(encrypt(data.getBytes(StandardCharsets.UTF_8), privateKey));
}
/**
* 公钥解密
* @param bytes 待解密字节数组
* @param publicKey 公钥
* @return 返回解密后的字节数组
*/
public static byte[] decrypt(final byte[] bytes, final String publicKey) throws Exception {
if(null == bytes || bytes.length <= 0) {
throw new RuntimeException("待解密字节数组不能为空");
}
if(StringUtils.isBlank(publicKey)) {
throw new RuntimeException("公钥不能为空");
}
PublicKey publicKeyObj = getPublicKey(publicKey);
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, publicKeyObj);
// 开始解密
// 暂存所有已加密字节,一起返回
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
byte[] tmpBytes = new byte[DECRYPT_BLOCK_SIZE];
int len;
while((len = inputStream.read(tmpBytes)) != -1) {
if(len != DECRYPT_BLOCK_SIZE) { // 如果加密数据不够 128 字节
byte[] buffer = new byte[len];
System.arraycopy(tmpBytes, 0, buffer, 0, len);
outputStream.write(cipher.doFinal(buffer));
} else {
outputStream.write(cipher.doFinal(tmpBytes));
}
}
outputStream.flush();
return outputStream.toByteArray();
}
/**
* 对给定的字符串进行解密(该字符串采用Base64编码)
* @param data 代码解密的Base64字符串
* @param publicKey 公钥
* @return 返回解密成功的字符串,默认使用UTF-8编码
*/
public static String decrypt(final String data, final String publicKey) throws Exception {
return new String(decrypt(Base64.decodeBase64(data), publicKey), StandardCharsets.UTF_8);
}
}使用方法如下:
public class Demo {
/** 公钥 */
private static String PUBLIC_KEY = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCuOFMwnouXWEueTm2Qmua5oo8J7frN96DoSDtw11ObrfvfVKu91GcjPlF/ynUeyjwPuzmi+bkCIDs2wUn0wz3CU52o4e1drzLiDOhGGqAb+cj5//o9mUVRJGrfzZyEePW8/gaRK3Q1iqu8hkBXbWGIkGFsbc3DJdkWlkd+Y6fHGwIDAQAB";
/** 私钥 */
private static String PRIVATE_KEY = "MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAK44UzCei5dYS55ObZCa5rmijwnt+s33oOhIO3DXU5ut+99Uq73UZyM+UX/KdR7KPA+7OaL5uQIgOzbBSfTDPcJTnajh7V2vMuIM6EYaoBv5yPn/+j2ZRVEkat/NnIR49bz+BpErdDWKq7yGQFdtYYiQYWxtzcMl2RaWR35jp8cbAgMBAAECgYA4ETJcjDl6PFUhnjXOertT9Ie591dmn5GuD0jp2LI0gLp1NgeLMOb8RZru2FX20bigi21SELHEiGDmDzBgz9B4x9lY8IIoB52FZdd+YgSVvXV/hA9Ikf1HClixC1DrixJ6/O/4e4r8uwdeTyVZvhVmf8Q37hfCRSKGCF5+plds0QJBAOltOgzTjF3iSjCjjXKprsaZZvgFaq+2/vmjzJvfDepBWU76MV+B5BB63n7C9S9jden+70qyCdATbLcezuEZCjkCQQC/EVzPNnsUre7u46bngTnkgVXcjcDler4BLBgDUCnJE06PDar48rcrEzK+0w3kCXN74ZzNFCt4A/1SKK9zh6vzAkBHfr39+bmPc+T3WtDTIue2SnwAUWBo62rTOXlM8JfJfTSGfRksQJOC/K8zMjF4z0TpY70VKszYn2p3+AazaUD5AkBNUSFVWJ6Fx7ygPs8Tb1+V8CBml5YvRnQM1WMCNDY0f/OSP92nz8//Rk2Kmq1MUebBgpKJClhswHCKBpy5C3WxAkB/prC/JNPP37P/G1+nALQpJ1kascODroWcS1x8BeLLHfCnSdYcI5uTLVzpBt/IfajEHCIDgW+yWJigqjf6DvjX";
public static void main(String[] args) throws Exception {
String value = "hello world";
// 加密
String result = RSAEncrypt.encrypt(value, PRIVATE_KEY);
System.out.println("密文:" + result);
// 解密
String result2 = RSAEncrypt.decrypt(result, PUBLIC_KEY);
System.out.println("明文:" + result2);
}
}运行示例,输出如下:
密文:c3Q7zAqiO8Vqp49yUBztx4FyYJub63hWm5qovDIfP9N8Zh4O4EBYC2mbdqigjO2xCaIUokFQwxuaZ/2oo6UJ6b3wxvijyfWAydiRvNKop4ewpJPfVLloZ3DAQ4aBXNJxhbas+kJa2obz3K0uYnSHEvUJr/T07GGcFbig0hx/Q7g= 明文:hello world