Java使用非对称数据加密RSA加密解密

  emmmmmm就是呢,我今天研究了一下非对称数据加密RSA的使用,算法什么的暂时不研究,加密算法还有很多,以后再研究吧,就酱(>人<;)。非对称加密算法需要两个密钥:公开密钥(publicKey)和私有密钥(privateKey);如果用公有密钥加密,对应的就是要私有密钥才能解密;反过来就是私钥加密,公钥解密。

  然后就来实现一下RSA加密的工具类吧

  注意:RSA加密明文最大长度是117字节,解密要求密文最大长度为128字节,所以再加密和解密的时候要分段进行,就是每117字节就加密,然后再把这一节节拼起来。

  1 public class RSAUtil {
  2
  3     public static String KEY_PAIRGENO = "RSA";
  4     public static String PUBLIC_KEY = "PUBLIC_KEY";
  5     public static String PRIVATE_KEY = "PRIVATE_KEY";
  6     public static final String CHARSET = "UTF-8";
  7
  8     public static HashMap<String, String> keyMap = new HashMap<>(2);
  9
 10     public static void init() throws Exception {
 11         KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance(KEY_PAIRGENO);
 12         keyPairGen.initialize(1024);
 13         KeyPair keyPair = keyPairGen.generateKeyPair();
 14         String publicKey = getPublicKeyStr(keyPair.getPublic());
 15         String privateKey = getPrivateKeyStr(keyPair.getPrivate());
 16
 17         keyMap.put(PUBLIC_KEY, publicKey);
 18         keyMap.put(PRIVATE_KEY,privateKey);
 19     }
 20
 21
 22     private static String getPrivateKeyStr(PrivateKey privateKey) throws Exception {
 23         return Base64.encodeBase64URLSafeString(privateKey.getEncoded());
 24     }
 25
 26     private static String getPublicKeyStr(PublicKey publicKey) throws Exception {
 27         return Base64.encodeBase64URLSafeString(publicKey.getEncoded());
 28     }
 29
 30     /**
 31      * 把字符串公钥转为 RSAPublicKey 公钥
 32      */
 33     public static RSAPublicKey getPublicKey(String publicKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
 34         //通过X509编码的Key指令获得公钥对象
 35         KeyFactory keyFactory = KeyFactory.getInstance(KEY_PAIRGENO);
 36         X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(Base64.decodeBase64(publicKey));
 37         RSAPublicKey key = (RSAPublicKey) keyFactory.generatePublic(x509KeySpec);
 38         return key;
 39     }
 40
 41     /**
 42      * 把字符串私钥转为 RSAPrivateKey 私钥
 43      */
 44     public static RSAPrivateKey getPrivateKey(String privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException {
 45         //通过PKCS#8编码的Key指令获得私钥对象
 46         KeyFactory keyFactory = KeyFactory.getInstance(KEY_PAIRGENO);
 47         PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(Base64.decodeBase64(privateKey));
 48         RSAPrivateKey key = (RSAPrivateKey) keyFactory.generatePrivate(pkcs8KeySpec);
 49         return key;
 50     }
 51
 52     /**
 53      * 公钥加密,  加密明文最大长度是117字节
 54      */
 55     public static String  encryptByPublicKey(String msg, RSAPublicKey publicKey) throws Exception{
 56         Cipher cipher = Cipher.getInstance(KEY_PAIRGENO);
 57         cipher.init(Cipher.ENCRYPT_MODE,publicKey);
 58         int keySize = publicKey.getModulus().bitLength();//1024
 59         byte[] data = msg.getBytes(CHARSET);
 60         byte[] encryptedData = rsaSplitCode(cipher, data, Cipher.ENCRYPT_MODE, keySize);
 61         String mi= Base64.encodeBase64URLSafeString(encryptedData);
 62         return mi;
 63
 64
 65     }
 66
 67     /*
 68      * 私钥解密,解密要求密文最大长度为128字节
 69      * */
 70     public static String decryptByPrivateKey(String rsaMsg, RSAPrivateKey privateKey) throws Exception{
 71         Cipher cipher = Cipher.getInstance(KEY_PAIRGENO);
 72         cipher.init(Cipher.DECRYPT_MODE, privateKey);
 73         int keySize = privateKey.getModulus().bitLength();//长度是1024
 74         byte[] data = Base64.decodeBase64(rsaMsg);
 75         byte[] decryptedData = rsaSplitCode(cipher, data, Cipher.DECRYPT_MODE, keySize);
 76         String ming = new String(decryptedData, CHARSET);
 77         return ming;
 78     }
 79
 80     /*私钥加密*/
 81     public static String encryptByPrivate(String msg, RSAPrivateKey privateKey) throws Exception{
 82         Cipher ciper = Cipher.getInstance(KEY_PAIRGENO);
 83         ciper.init(Cipher.ENCRYPT_MODE,privateKey);
 84         int keySize = privateKey.getModulus().bitLength();
 85         byte[] data = msg.getBytes(CHARSET);
 86         byte[] encryptedData = rsaSplitCode(ciper, data, Cipher.ENCRYPT_MODE,keySize);
 87         String mi = Base64.encodeBase64URLSafeString(encryptedData);
 88         return mi;
 89     }
 90
 91     /*公钥解密*/
 92     public static String decrytByPublic(String msg, RSAPublicKey publicKey) throws Exception{
 93         Cipher ciper = Cipher.getInstance(KEY_PAIRGENO);
 94         ciper.init(Cipher.DECRYPT_MODE, publicKey);
 95         int keySize = publicKey.getModulus().bitLength();
 96         byte[] data = Base64.decodeBase64(msg);
 97         byte[] decryptedData = rsaSplitCode(ciper, data, Cipher.DECRYPT_MODE,keySize);
 98         String ming = new String(decryptedData,CHARSET);
 99         return ming;
100     }
101
102
103
104     private static byte[] rsaSplitCode(Cipher cipher, byte[] data,int opmode ,int keySize){
105         int maxBlock = 0;
106         if(opmode == Cipher.DECRYPT_MODE)
107             maxBlock = keySize / 8;//解密要求最大长度是128
108         else
109             maxBlock = keySize / 8 -11; //加密要求最大长度是117
110
111         int inputLen = data.length;
112         ByteArrayOutputStream out = new ByteArrayOutputStream();
113         int offSet = 0;
114         byte[] cache;
115         int i = 0;
116         // 对数据分段解密
117         try {
118             while (inputLen - offSet > 0) {
119                  if (inputLen - offSet > maxBlock) {
120                      cache = cipher.doFinal(data, offSet, maxBlock);
121                  } else {
122                      cache = cipher.doFinal(data, offSet, inputLen - offSet);
123                  }
124                   out.write(cache, 0, cache.length);
125                  i++;
126                  offSet = i * maxBlock;
127              }
128             byte[] bytes = out.toByteArray();
129             out.close();
130             return bytes;
131         } catch (Exception e) {
132             throw new RuntimeException("加解密阀值为["+maxBlock+"]的数据时发生异常", e);
133         }
134     }
135
136
137
138
139
140     public static void main(String[] args) throws Exception {
141         init();
142         String msg = "我是冬竹";
143         System.out.println("公钥加密-私钥解密:");
144         String mi  =  encryptByPublicKey(msg, getPublicKey(keyMap.get(PUBLIC_KEY)));
145         System.out.println("密文:" + mi);
146
147         String ming = decryptByPrivateKey(mi ,  getPrivateKey(keyMap.get(PRIVATE_KEY)));
148         System.out.println("明文:" + ming);
149
150         System.out.println("私钥加密-公钥解密:");
151         String mi2 =  encryptByPrivate(msg, getPrivateKey(keyMap.get(PRIVATE_KEY)));
152         System.out.println("密文:" + mi2);
153
154         String ming2 = decrytByPublic(mi2 ,  getPublicKey(keyMap.get(PUBLIC_KEY)));
155         System.out.println("明文:" + ming);
156     }
157
158 }

  

  这这这好长啊........

  说一下这个过程:

    1.  keyPair.getPublic() 获得的字节数组  用encodeBase64URLSafeString() 编码成字符串,也就是我们有时候用的那种很多字母的那种公钥(私钥)

    2.  用decodeBase64()  把公钥解码成字节数组,然后通过X509编码的Key指令获得公钥对象 RSAPublicKey

 加密字符串的过程:

    1.   msg.getBytes() 获得字符数组, 然后用rsaSplitCode() 方法加密,再用encodeBase64URLSafeString编码成字符串(密文)

 解密字符串的过程:

    1.  decodeBase64() 把密文解码成字符数组,再用new String()方法转为字符串

然后我用的Base64类是commons-net-3.1.jar  里的,这个是我的maven仓库里(maven真的太方便了(●ˇ?ˇ●))

放上这个:https://github.com/MoisAbby/XZUtils, 以后会把我攒的好用的东西都放上来

原文地址:https://www.cnblogs.com/MoisAbby/p/8443425.html

时间: 2024-08-12 09:55:53

Java使用非对称数据加密RSA加密解密的相关文章

Java &amp; PHP &amp; Javascript 通用 RSA 加密 解密 (长字符串)

系统与系统的数据交互中,有些敏感数据是不能直接明文传输的,所以在发送数据之前要进行加密,在接收到数据时进行解密处理:然而由于系统与系统之间的开发语言不同. 本次需求是生成二维码是通过java生成,由php来解密.基于这类需求所以选择了RSA进行加解密. 生成RSA公私钥分成三步生成RSA公私钥,第1.2步可以满足php的使用,由于java的私钥要转化为PKCS8格式才能使用,所以执行第3步来实现. 还有一种加密方式参考: DES ECB 模式 JAVA PHP C# 实现 加密 解密 兼容 .

JAVA实现RSA加密解密 非对称算法

首先RSA是一个非对称的加密算法,所以在使用该算法加密解密之前,必须先行生成密钥对,包括公钥和私钥 JDK中提供了生成密钥对的类KeyPairGenerator,实例如下: public static Map<String, Object> genKeyPair() throws Exception { // 获取公钥私钥密钥对的生成器 KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA"); // 初始化确定密

RSA加密解密及数字签名Java实现--转

RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院工作.RSA就是他们三人姓氏开头字母拼在一起组成的. RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密算法. RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密. 关于RSA算法

RSA加密解密及数字签名Java实现

RSA公钥加密算法是1977年由罗纳德·李维斯特(Ron Rivest).阿迪·萨莫尔(Adi Shamir)和伦纳德·阿德曼(Leonard Adleman)一起提出的.当时他们三人都在麻省理工学院工作.RSA就是他们三人姓氏开头字母拼在一起组成的.RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的绝大多数密码攻击,已被ISO推荐为公钥数据加密算法.RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密.关于RSA算法的原理

Java使用RSA加密解密签名及校验

由于项目要用到非对称加密解密签名校验什么的,于是参考<Java加密解密的艺术>写一个RSA进行加密解密签名及校验的Demo,代码很简单,特此分享! RSA加密解密类: package com.ihep; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; imp

C# Java间进行RSA加密解密交互

引用:http://blog.csdn.net/dslinmy/article/details/37362661 这里,讲一下RSA算法加解密在C#和Java之间交互的问题,这两天纠结了很久,也看了很多其他人写的文章,颇受裨益,但没能解决我的实际问题,终于,还是被我捣鼓出来了. 首先,介绍一下写这代码的目的:完成webService验证问题,服务器端采用C#开发,客户端采用Java开发.服务器端给客户端提供公钥,已进行数据加密,客户端加密后提数据提交给服务器,服务器用私钥对数据解密,进行验证.

C# 与JAVA 的RSA 加密解密交互,互通,C#使用BouncyCastle来实现私钥加密,公钥解密的方法

因为C#的RSA加密解密只有公钥加密,私钥解密,没有私钥加密,公钥解密.在网上查了很久也没有很好的实现.BouncyCastle的文档少之又少.很多人可能会说,C#也是可以的,通过Biginteger开源类来实现,不过那个是有一个文章,不过他加密出来的是16进制结果的.根本不能和JAVA互通.连加密出来的都不和C#原生的加密出来的结果格式一样.所以还是没有好的解决方法. 接下来还是不断的找资料,找方法.找朋友找同事.个个都找.问题是有的,方法也是有的,所以总结各路大神之后写了这个类.实现了私钥加

C#-java RSA加密解密

using Org.BouncyCastle.Math;using Org.BouncyCastle.Crypto.Parameters;using Org.BouncyCastle.Security;using Org.BouncyCastle.Asn1.X509;using Org.BouncyCastle.X509;using Org.BouncyCastle.Asn1.Pkcs;using Org.BouncyCastle.Pkcs;using System;using System.S

RSA加密解密及RSA加签验签

RSA安全性应用场景说明 在刚接触RSA的时候,会混淆RSA加密解密和RSA加签验签的概念.简单来说加密解密是公钥加密私钥解密,持有公钥(多人持有)可以对数据加密,但是只有持有私钥(一人持有)才可以解密并查看数据:加签验签是私钥加签公钥验签,持有私钥(一人持有)可以加签,持有公钥(多人持有)可以验签. 在金融行业在设计到数据交互传输的时候,需要考虑数据的安全性问题.下文通过介绍RSA的加密和加签两个特性,说明RSA加密技术在保障数据传输过程中的安全性以及实现数据的防篡改和防否机制的应用场景及代码