RSA是由三位数学家Rivest、Shamir 和 Adleman 发明的非对称加密算法,这种算法非常可靠,秘钥越长,就越难破解。

目前被破解的最长RSA秘钥是768个二进制位,长度超过768位的秘钥还无法破解,但随着计算能力的增强,以后被破解到多少位还是未知数。就目前而言,1024位的秘钥属于基本安全,2048位的秘钥属于极其安全。

RSA是一种非对称加密算法,也就是加密和解密使用的不是同一把秘钥:公钥加密-私钥解密、私钥加密-公钥解密。

RSA算法在计算机网络中被普遍应用,如:https、ssh等。

该算法还可以实现应用许可证(license),有以下几个步骤:

  1. 甲方构建密钥对(公钥和私钥,公钥给对方,私钥留给自己)。

  2. 甲方使用私钥加密许可证,然后用私钥对加密的许可证进行签名,并把这些发送给乙方。

  3. 乙方使用公钥、签名来验证待解密许可证是否有效(许可的来源是否有效、许可的内容是否被篡改),如果有效使用公钥对许可证解密。

  4. 乙方使用公钥加密数据,向甲方发送经过加密后的数据;甲方获得加密数据,通过私钥解密。

注意:RSA加密要求明文最大长度117字节,解密要求密文最大长度为秘钥长度除以8(1024位秘钥 / 8 = 128,2048位秘钥 / 8 = 256),所以在加密和解密的过程中需要分块进行。

Java实现RSA:

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.lang3.StringUtils;import javax.crypto.Cipher;
import java.io.ByteArrayOutputStream;
import java.security.*;
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;public class RSAUtil {private static final String KEY_ALGORITHM = "RSA";       //加密算法RSAprivate static final String SIGNATURE_ALGORITHM = "MD5withRSA";  //签名算法//RSA本身的限制:最大加密明文大小 = 117private static final int MAX_ENCRYPT_BLOCK = 117;//RSA本身的限制:最大解密密文大小 = keySize / 8 = 128 或 256private static int MAX_DECRYPT_BLOCK = 128;private enum KeyType {PUBLIC_KEY, PRIVATE_KEY}/*** 指定字符串生成密钥对(公钥和私钥)** @param randomKey 加密的密码* @param keySize   秘钥的长度:1024 或 2048* @return* @throws Exception*/public static Map<KeyType, Object> genKeyPair(String randomKey, int keySize) throws Exception {MAX_DECRYPT_BLOCK = keySize / 8;KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_ALGORITHM);if (StringUtils.isBlank(randomKey)) {   //不指定密码keyPairGen.initialize(keySize);} else {    //指定密码SecureRandom random = SecureRandom.getInstance("SHA1PRNG");random.setSeed(randomKey.getBytes());keyPairGen.initialize(keySize, random);}KeyPair keyPair = keyPairGen.generateKeyPair();RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();Map<KeyType, Object> keyMap = new HashMap<>(2);keyMap.put(KeyType.PUBLIC_KEY, publicKey);keyMap.put(KeyType.PRIVATE_KEY, privateKey);return keyMap;}/*** 用私钥对数据生成数字签名** @param data       已加密数据* @param privateKey 私钥(BASE64编码)* @return* @throws Exception*/public static String sign(byte[] data, String privateKey) throws Exception {byte[] keyBytes = Base64.decodeBase64(privateKey);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PrivateKey privateK = keyFactory.generatePrivate(pkcs8KeySpec);Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initSign(privateK);signature.update(data);return Base64.encodeBase64String(signature.sign());}/*** 用公钥校验数字签名** @param data      已加密数据* @param publicKey 公钥(BASE64编码)* @param sign      数字签名* @return* @throws Exception*/public static boolean verify(byte[] data, String publicKey, String sign) throws Exception {byte[] keyBytes = Base64.decodeBase64(publicKey);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);PublicKey publicK = keyFactory.generatePublic(keySpec);Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);signature.initVerify(publicK);signature.update(data);return signature.verify(Base64.decodeBase64(sign));}/*** 私钥加密** @param data       数据* @param privateKey 私钥(BASE64编码)* @return* @throws Exception*/public static byte[] encryptByPrivateKey(byte[] data, String privateKey) throws Exception {byte[] keyBytes = Base64.decodeBase64(privateKey);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  //获取算法cipher.init(Cipher.ENCRYPT_MODE, privateK);                     //设置加密模式,并指定私钥// 对数据分段加密int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] buffer;int i = 0;while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {buffer = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);} else {buffer = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(buffer, 0, buffer.length);i++;offSet = i * MAX_ENCRYPT_BLOCK;}byte[] encryptedData = out.toByteArray();out.close();return encryptedData;}/*** 私钥解密** @param encryptedData 已加密数据* @param privateKey    私钥(BASE64编码)* @return* @throws Exception*/public static byte[] decryptByPrivateKey(byte[] encryptedData, String privateKey) throws Exception {byte[] keyBytes = Base64.decodeBase64(privateKey);PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key privateK = keyFactory.generatePrivate(pkcs8KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  //获取算法cipher.init(Cipher.DECRYPT_MODE, privateK);                     //设置解密模式,并指定私钥// 对数据分段解密int inputLen = encryptedData.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] buffer;int i = 0;while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_DECRYPT_BLOCK) {buffer = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);} else {buffer = cipher.doFinal(encryptedData, offSet, inputLen - offSet);}out.write(buffer, 0, buffer.length);i++;offSet = i * MAX_DECRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();return decryptedData;}/*** 公钥加密** @param data      数据* @param publicKey 公钥(BASE64编码)* @return* @throws Exception*/public static byte[] encryptByPublicKey(byte[] data, String publicKey) throws Exception {byte[] keyBytes = Base64.decodeBase64(publicKey);X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicK = keyFactory.generatePublic(x509KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  //获取算法cipher.init(Cipher.ENCRYPT_MODE, publicK);                      //设置加密模式,并指定公钥// 对数据分段加密int inputLen = data.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] buffer;int i = 0;while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {buffer = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);} else {buffer = cipher.doFinal(data, offSet, inputLen - offSet);}out.write(buffer, 0, buffer.length);i++;offSet = i * MAX_ENCRYPT_BLOCK;}byte[] encryptedData = out.toByteArray();out.close();return encryptedData;}/*** 公钥解密** @param encryptedData 已加密数据* @param publicKey     公钥(BASE64编码)* @return* @throws Exception*/public static byte[] decryptByPublicKey(byte[] encryptedData, String publicKey) throws Exception {byte[] keyBytes = Base64.decodeBase64(publicKey);X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);Key publicK = keyFactory.generatePublic(x509KeySpec);Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());  //获取算法cipher.init(Cipher.DECRYPT_MODE, publicK);                      //设置解密模式,并指定公钥// 对数据分段解密int inputLen = encryptedData.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offSet = 0;byte[] buffer;int i = 0;while (inputLen - offSet > 0) {if (inputLen - offSet > MAX_DECRYPT_BLOCK) {buffer = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);} else {buffer = cipher.doFinal(encryptedData, offSet, inputLen - offSet);}out.write(buffer, 0, buffer.length);i++;offSet = i * MAX_DECRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();return decryptedData;}/*** 获取私钥** @param keyMap* @return* @throws Exception*/public static String getPrivateKey(Map<KeyType, Object> keyMap) {Key key = (Key) keyMap.get(KeyType.PRIVATE_KEY);return Base64.encodeBase64String(key.getEncoded());}/*** 获取公钥** @param keyMap* @return* @throws Exception*/public static String getPublicKey(Map<KeyType, Object> keyMap) throws Exception {Key key = (Key) keyMap.get(KeyType.PUBLIC_KEY);return Base64.encodeBase64String(key.getEncoded());}public static void main(String[] args) throws Exception {String password = "123456";     //加解密的密码int keySize = 2048;     //秘钥的长度:1024 或 2048Map<KeyType, Object> keyMap = RSAUtil.genKeyPair(password, keySize);String publicKey = RSAUtil.getPublicKey(keyMap);String privateKey = RSAUtil.getPrivateKey(keyMap);System.out.println("publicKey : " + publicKey);System.out.println("privateKey : " + privateKey);System.out.println();System.out.println("公钥加密 -- 私钥解密");String data = "RSA 非对称加密算法:公钥加密 -- 私钥解密";System.out.println("明文 :" + data);byte[] encryptData = RSAUtil.encryptByPublicKey(data.getBytes(), publicKey);System.out.println("公钥加密 :" + Hex.encodeHexString(encryptData));byte[] decryptData = RSAUtil.decryptByPrivateKey(encryptData, privateKey);System.out.println("私钥解密 :" + new String(decryptData));System.out.println();System.out.println("私钥加密 -- 公钥解密");String data2 = "RSA 非对称加密算法:私钥加密 -- 公钥解密";System.out.println("明文 :" + data2);byte[] encryptData2 = RSAUtil.encryptByPrivateKey(data2.getBytes(), privateKey);System.out.println("私钥加密 :" + Hex.encodeHexString(encryptData2));byte[] decryptData2 = RSAUtil.decryptByPublicKey(encryptData2, publicKey);System.out.println("公钥解密 :" + new String(decryptData2));System.out.println();System.out.println("私钥签名 -- 公钥验证签名");String sign = RSAUtil.sign(encryptData2, privateKey);System.out.println("私钥签名 :" + sign);boolean status = RSAUtil.verify(encryptData2, publicKey, sign);System.out.println("公钥验证签名 :" + status);}
}

Java实现非对称加密算法-RSA加解密相关推荐

  1. Java实现对称加密算法-AES加解密

    AES(Advanced Encryption Standard)意思是高级加密标准,是一种区块加密标准.这个标准用来替代原先的DES,且已经被广泛使用. DES使用56位密钥,所以比较容易被破解. ...

  2. RSA加解密用途简介及java示例

    在公司当前版本的中间件通信框架中,为了防止非授权第三方和到期客户端的连接,我们通过AES和RSA两种方式的加解密策略进行认证.对于非对称RSA加解密,因为其性能耗费较大,一般仅用于认证连接,不会用于每 ...

  3. 数据传输加密——非对称加密算法RSA+对称算法AES(适用于java,android和Web)

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 转载请注明出处:http://blog.csdn.net/chay_chan/article/details/58605605 数据 ...

  4. 与非java语言使用RSA加解密遇到的问题:algid parse error, not a sequence

    遇到的问题 在一个与Ruby语言对接的项目中,决定使用RSA算法来作为数据传输的加密与签名算法.但是,在使用Ruby生成后给我的私钥时,却发生了异常:IOException: algid parse ...

  5. Java加密技术(四)——非对称加密算法RSA

    转自:http://snowolf.iteye.com/blog/381767 接下来我们介绍典型的非对称加密算法--RSA RSA     这种算法1978年就出现了,它是第一个既能用于数据加密也能 ...

  6. java js 非对称加密算法_Java加密技术(四)——非对称加密算法RSA

    Java非对称加密算法rsa 接下来我们介绍典型的非对称加密算法--RSA RSA 这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法.它易于理解和操作,也很流行.算法的名字 ...

  7. Java进阶(七)Java加密技术之非对称加密算法RSA

    Java加密技术(四)--非对称加密算法RSA 非对称加密算法--RSA 基本概念 非对称加密算法是一种密钥的保密方法. 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥(priv ...

  8. 前后端java+vue 实现rsa 加解密与摘要签名算法

    RSA有两个密钥,一个是公开的,称为公开密钥:一个是私密的,称为私密密钥. 特点: 公开密钥是对大众公开的,私密密钥是服务器私有的,两者不能互推得出. 用公开密钥对数据进行加密,私密密钥可解密:私密密 ...

  9. openresty 与 java RSA加解密

    上一篇搞定了openresty与java之间的aes加解密.这一篇就来说说openresty与java之间RSA的加解密.在测试的过程中.发现了与aes同样的问题.就是openresty支持的填充模式 ...

最新文章

  1. 如何具体学习计算机视觉
  2. Android教你打造独一无二的刷新加载框架
  3. Mybatis 缓存系统源码解析
  4. BLE-NRF51822-实现简单扫描器
  5. boost::spirit模块实现罗马数字解析器(演示符号表)的测试程序
  6. TypeError: object.__init__() takes no parameters异常报错分析
  7. java实现九九乘法表的输出
  8. 前端学习(2468):echart复习电商管理通过路由加载数据
  9. mysql mac 中文乱码_Mac mysql 解决中文乱码
  10. 基于JavaSwing ATM取款机系统的设计和实现
  11. 封装的一个http请求struct,包含:头、cookie、代理、超时、本地ip切换
  12. 嵌入式电路设计(第一个商业pcb电路图绘制)
  13. 56. mysqli 扩展库(3)
  14. 禁用驱动程序强制签名(终极办法)
  15. 谷歌输入法linux版本下载,技术|在Ubuntu下安装谷歌输入法
  16. 无线电通信之父:马可尼
  17. arm板上简单运行main.cpp
  18. 解决django admin表的外键关联数据过多响应时间过长问题
  19. iOS Core Animation 简明系列教程
  20. 【编程题 动态规划】最长公共子序列(详细注释 易懂)

热门文章

  1. .net开发中常用的第三方组件
  2. 代码阅读软件kscope源码安装指导
  3. 如何在 Windows 2000 中安装 Microsoft 环回适配器
  4. 做点RouteOS方面的备忘,关于流量监控限速的
  5. Linux -- 基于zookeeper的java api(二)
  6. 以鶸ice为例,手撸一个解释器(一)明确目标
  7. 如何使用WebUploader。
  8. 启动Tomcat服务时,出现org.apache.catalina.startup.VersionLoggerListener报错
  9. HTML超文本标记语言(八)——表单form
  10. Ext JS学习第二天 我们所熟悉的javascript(一)