废话不多说,直接上代码,不懂的看注释。代码如下:
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