首页 > 其他分享 >【RSA加密】初探RSA并简单使用

【RSA加密】初探RSA并简单使用

时间:2022-12-02 22:09:25浏览次数:66  
标签:Exception return String RSA json 初探 加密 data public


RSA简介,这里贴上一篇博客,讲的很详细,通俗易懂

初步理解之后,下面是关于RSA的简单使用:

这里贴上一篇优秀的前端加密,后端解密的博客,简单使用的话是可以了。

看完上面两篇博客,就够用的了,我这里记录一下目前项目中用到的加密方式:

首先是两对秘钥:前端一对,后端一对:
ejtConfig.java,下面的秘钥都是不全的,随机删除了一些内容。
在线生成秘钥:​​​http://web.chacuo.net/netrsakeypair​​ 或者参考这篇博客,在自己电脑上生成秘钥

public class ejtConfig {
//RSA 公钥1
public static final String PUBLIC_KEY="MIGfMA0GCSqGSIb3DQEBAQUAUuy7mKYZKFwsDGbg7EWWFo8mNGQKPM9kAvIam/p+zBrEpQCgDYZZp0kMZUgCBdp543AzxiQJTHN6+LrTYpZlyot0We0QzJHbsLJmnpvKPOmpfYANUfB63PoNV9ZFep/qpTnNquCDKVfY1QUEfJDLgQIDAQAB";
//RSA 私钥1
public static final String PRIVATE_KEY="MIICdQIBADANBgkqhkZ7RDMkduwsmaem8o84xuhvpTQbhqMM8GtyGcqCal9gA1R8Hrc+g1X1kV6n+qlOc2q4IMpV9jVBQR8kMuBAgMBAAECgYAVZloFC+fZmrCMrH/Z7uUa4yH7DmGr8NKH1wckYlHKFfZ3whBeswvvN+YetjzkeVh4i6mkwovjrW4q4wIuQZUexDqguleqbmdz5OEZ0jLItfX0xdRlWogzE3VQnxLu+9cNd3J6OBcNmvfCWaUCQQDeUfArljGsDQCGUhvZFFiifX+r5GrO1f2clW+/XaVDu9sYMmbLO2NbNAxsBqRpautAkBf3gQ0Glc2EuZMeA59f68Mxpkbo4gqMsmsQLExnSt8mi3+1LvtzF8PvHy3Ipi7JK6suFRFvGb/bm2Mdy695aNBAkANlgpMT5hngD/o9XmYMYMdIvg7Y/EXBMLD3+bdHRiOusUSe5VPCVsPcNkWkUQJOGVG55vsPbmiq+SpNK7a+bndAkBKelKXC1GmjW0CeyEXTGG/aRzUXGPmsMk8Nc0t0yQiu+FTFR/P0UfIzZaE0GaIzXA7H7/Wwk/EZ4p/eG6WALof";
//RSA 公钥2
public static final String PUBLIC_KEY2="MIGfMA0GCSqGSIbQKBgQDL07hhkiy0e3OAHnw4Uhqo82a59BhyKscIp4XaRJ5B0EchJ0qFt6qOwTRIQtm1qfQw0EOH+XhfKUy+/UKPfnEVDRGS3dwS5rrAYY6GeOngnoQ9qgzvho1S44onkYnQlKPUUYsQE9QwRC0ElMSJNWObQIDAQAB";
//RSA 私钥2
public static final String PRIVATE_KEY2="MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAMvTuGGSLLR7c4AefDhSGqjzZrn0GHIqxwinhdpGxHy7bwnkHQRyE3qo7BNEhC2bW79Qo9+zOucRUNEZA9y26ZLd3BLmusBhjoZ46eCehD2qDO+GjVLjiie5Mh1wSRidCUo9RRixAT1DBELQSUxIk1Y5tAgMBAAECgYAkY2PjZ2k7v15bXRXoKCBhmMZUe3aVAPNQiJnDeuLT7TmQ9Zx93yCVwVqEBhNi4P1IuXu1aTC+KFeqYM4rzHtNBvN6lkcm+jQaMRCoLN5/CTQjHE7g/SvBNGSX7Tyf6JUB/E7IGCbSvfT+Mgu+noqPyPjezQjGkdNKeGe+sQJBAPhbkny7rX3cwul8sMA3IgZQYxvtcqdJVeQJkUhcXCu7K5Y6JdQHf4VOfRBMCQQDWeqOQucpb7XeYdZPFuUiy1Hi3jFtH4NwNKjiIEwj6jfRKJaX+ByUSGfsb2Wp1bbfhEltiQATETN/AkBVaAgrWklVYJ/WO0lDI4sCpgy1xFbnI9WukCepy6v+QC1Cnt5AGiPFOxNW6qGn+b3o/ZHBqKot42vAkB2aSLghhJYilQa0d8RrGecg31aKJ1Eo7oZcpPfXFL6sJWUPZv0Z5kDWps5r3tnyknF2QKRrzHVWEAg+Y8mde/Pvk7hrSRco2zji4jyFY6TE4NWTgxvM0Grma91H3coqfgj/10MhIGgqtW3ePVBZFrUfcsKuNOiGdyDQ==";
}

秘钥的使用规则:
(1) 使用RSA加密;
(2) 生成两对密钥,公钥1 私钥1,公钥2 私钥2,后台存有两对密钥,客户端存有公钥1、私钥2;
(3) 请求数据:客户端使用公钥1加密后发给后台,后台使用私钥1解密;
(4) 返回数据:后台使用公钥2加密后返回给客户端,客户端使用私钥2解密;

工具类RSAUtils.java
需要添加依赖:

<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>

RSAUtils.java

package com.lin.util;

import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.Key;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

import javax.crypto.Cipher;

import org.apache.commons.codec.binary.Base64;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;




/**
* Created by humf.需要依赖 commons-codec 包
*/
public class RSAUtils {
public static final String KEY_ALGORITHM = "RSA";
public static final String SIGNATURE_ALGORITHM = "MD5withRSA";

private static final String PUBLIC_KEY = "RSAPublicKey";
private static final String PRIVATE_KEY = "RSAPrivateKey";

public static byte[] decryptBASE64(String key) {
return Base64.decodeBase64(key);
}

public static String encryptBASE64(byte[] bytes) {
return Base64.encodeBase64String(bytes);
}

/**
* 用私钥对信息生成数字签名
*
* @param data 加密数据
* @param privateKey 私钥
* @return
* @throws Exception
*/
public static String sign(byte[] data, String privateKey) throws Exception {
// 解密由base64编码的私钥
byte[] keyBytes = decryptBASE64(privateKey);
// 构造PKCS8EncodedKeySpec对象
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取私钥匙对象
PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 用私钥对信息生成数字签名
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initSign(priKey);
signature.update(data);
return encryptBASE64(signature.sign());
}

/**
* 校验数字签名
*
* @param data 加密数据
* @param publicKey 公钥
* @param sign 数字签名
* @return 校验成功返回true 失败返回false
* @throws Exception
*/
public static boolean verify(byte[] data, String publicKey, String sign)
throws Exception {
// 解密由base64编码的公钥
byte[] keyBytes = decryptBASE64(publicKey);
// 构造X509EncodedKeySpec对象
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
// KEY_ALGORITHM 指定的加密算法
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
// 取公钥匙对象
PublicKey pubKey = keyFactory.generatePublic(keySpec);
Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);
signature.initVerify(pubKey);
signature.update(data);
// 验证签名是否正常
return signature.verify(decryptBASE64(sign));
}

public static byte[] decryptByPrivateKey(byte[] data, String key) throws Exception{
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(data);
}

/**
* 解密<br>
* 用私钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPrivateKey(String data, String key)
throws Exception {
return decryptByPrivateKey(decryptBASE64(data),key);
}

/**
* 解密<br>
* 用公钥解密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] decryptByPublicKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据解密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.DECRYPT_MODE, publicKey);
return cipher.doFinal(data);
}

/**
* 加密<br>
* 用公钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPublicKey(String data, String key)
throws Exception {
// 对公钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得公钥
X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key publicKey = keyFactory.generatePublic(x509KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
//System.out.println(cipher.doFinal(data.getBytes()).toString());
return cipher.doFinal(data.getBytes());
}

/**
* 加密<br>
* 用私钥加密
*
* @param data
* @param key
* @return
* @throws Exception
*/
public static byte[] encryptByPrivateKey(byte[] data, String key)
throws Exception {
// 对密钥解密
byte[] keyBytes = decryptBASE64(key);
// 取得私钥
PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
Key privateKey = keyFactory.generatePrivate(pkcs8KeySpec);
// 对数据加密
Cipher cipher = Cipher.getInstance(keyFactory.getAlgorithm());
cipher.init(Cipher.ENCRYPT_MODE, privateKey);
return cipher.doFinal(data);
}

/**
* 取得私钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPrivateKey(Map<String, Key> keyMap)
throws Exception {
Key key = (Key) keyMap.get(PRIVATE_KEY);
return encryptBASE64(key.getEncoded());
}

/**
* 取得公钥
*
* @param keyMap
* @return
* @throws Exception
*/
public static String getPublicKey(Map<String, Key> keyMap)
throws Exception {
Key key = keyMap.get(PUBLIC_KEY);
return encryptBASE64(key.getEncoded());
}

/**
* 初始化密钥
*
* @return
* @throws Exception
*/
public static Map<String, Key> initKey() throws Exception {
KeyPairGenerator keyPairGen = KeyPairGenerator
.getInstance(KEY_ALGORITHM);
keyPairGen.initialize(1024);
KeyPair keyPair = keyPairGen.generateKeyPair();
Map<String, Key> keyMap = new HashMap(2);
keyMap.put(PUBLIC_KEY, keyPair.getPublic());// 公钥
keyMap.put(PRIVATE_KEY, keyPair.getPrivate());// 私钥
return keyMap;
}
/**
* 解密参数并转换成json
* @param data
* @return
* @throws Exception
*/
public static JSONObject getContent(String data )throws Exception {
//获取参数
byte[] encryptByPrivateKey=null;
try {
encryptByPrivateKey = RSAUtils.decryptByPrivateKey(data,ejtConfig.PRIVATE_KEY );
} catch (Exception e) {
e.printStackTrace();
}

String decodedData =new String(encryptByPrivateKey,"UTF-8");
System.out.println("String:" + decodedData);
JSONObject obj=JSON.parseObject(decodedData);
System.out.println("obj:" + obj);
return obj;
}



public static void main(String[] args) throws Exception {
String aaaa="ju9oSvodOy4mCLb0c/6UP8nGIIoVO3vlJeJ0wrRkUeGjUQWWtpkBWHXW2oxClwbf0ysi2/I6/aBq80FVxUU8qhYpIFzGILYGlnmoEHJxrO1BZfPXLSCa18HorhNkNkdGiRi5SEWfIKktmxIozckwKGvEqLGHoNB8Un8/9EyuELM=";
/* Map<String, Key> keyMap = initKey();
String publicKey = getPublicKey(keyMap);
String privateKey = getPrivateKey(keyMap);
System.out.println(keyMap);
System.out.println("-----------------------------------");
System.out.println("公钥:"+publicKey);
System.out.println("-----------------------------------");
System.out.println("私钥:"+privateKey);
System.out.println("-----------------------------------");*/
JSONObject json=new JSONObject();
json.put("memberId", "16652");
json.put("accessKey", "e21b060017b4e911d14baa819905caa5");
// json.put("pageNum", "1");
// json.put("pageSize", "5");
// json.put("memberId", "1236");
// json.put("testingAreaInfo", "深圳");
/* json.put("Areaid","7");
json.put("Id","16639" );
json.put("Areainfo","8" );*/
String str =String.valueOf(json);
System.out.println("str:" + str);
byte[] aa=null;
try {
aa=RSAUtils.encryptByPublicKey(str,ejtConfig.PUBLIC_KEY);
} catch (Exception e1) {
e1.printStackTrace();
}
String base64 = Base64.encodeBase64String(aa);
System.out.println("base64:"+base64);

JSONObject obj1 = RSAUtils.getContent(aaaa);
System.out.println("obj1:" + obj1);

String name=URLEncoder.encode("测", "GBK");
String decode = URLDecoder.decode(name);
System.out.println(name);
System.out.println(decode);
}
}

后台对前台传来的加密数据data进行解密,提取参数,然后返回加密的token,这里用注册接口示例:

/**
* 注册接口
* @param request
* @param response
* @param data
* @return
*/
@RequestMapping("/memberRegister")
@ResponseBody
public JSONObject memberRegister(String data){
JSONObject json = null;
//====解密,并转为json字符串
try {
json = RSAUtils.getContent(data);
} catch (Exception e) {
e.printStackTrace();
return JsonUtil.getJson(50, null, "参数格式不对");
}
//解密结束,获取密文内容
String phoneNum = json.getString("phoneNum");
String password= json.getString("password");

//注册写入数据库之后,返回用户id和token(加密传输)
ShopMember member=shopMemberService.findByMemberPhone(phone);
//初始化用户token信息(token生成方式,参考我的另一篇博客,后续加上)
String initializeToken = appTokenRecordService.initializeToken(member.getMemberId());
JSONObject json = new JSONObject();
json.put("token", initializeToken);
json.put("memberId", member.getMemberId());
String str=String.valueOf(json);
byte[] aa = null;
try {
aa = RSAUtils.encryptByPublicKey(str,ejtConfig.PUBLIC_KEY2);
} catch (Exception e1) {
e1.printStackTrace();
}
String base64 = Base64.encodeBase64String(aa);
System.out.println(base64);
return JsonUtil.getJson(10, base64, "注册成功");
}

上面demo中要用到的一个工具类:JsonUtil.java

public class JsonUtil {
public static JSONObject getJson(int ret,Object result,String msg){
JSONObject json = new JSONObject();
json.put("ret", ret); //0失败 1成功
json.put("data", result); //返回数据
json.put("msg", msg); //返回消息
return json;
}
}

到这里,一个简单的RSA加密传输的demo就算结束了。


标签:Exception,return,String,RSA,json,初探,加密,data,public
From: https://blog.51cto.com/linmengmeng/5907575

相关文章

  • SpringBoot 实现密码加密以及登录成功token实现
    谨以此文章记录自己的学习过程,借以帮助有同样需求的小伙伴,实现的不完善,只是将大概的主要内容实现而已~一、demo所需的技术springBoot、springSecurity、mysql、lombok部......
  • [RoarCTF2019]babyRSA
    题目脚本代码:importsympyimportrandomdefmyGetPrime():A=getPrime(513)print(A)B=A-random.randint(1e3,1e5)print(B)returnsympy.nextPrime((B......
  • 跨平台开发:PhoneGap移动开发框架初探
    原文发表在:http://publish.itpub.net/a2010/1008/1111/000001111212.shtml目前,随着Google的Android手机和苹果的iphone手机的逐渐普及,越来越多开发......
  • java解加密(AES/CBC)异常:java.lang.SecurityException: JCE cannot authenticate the
    原文链接:https://blog.csdn.net/weixin_43048843/article/details/109200673对接第三方厂商需求时,需要对数据AES256进行解密,由于java本身不支持,需要添加依赖。一、版本适......
  • grub加密与解密
    前言grub默认无加密,用户可免密以单用户模式进入系统修改root密码。若想增强其安全性,可以将grub加密。GRUB2提供两种类型的密码保护:修改菜单条目时需要密码,但启动菜单......
  • Vue RSA加密
    1.安装jsencryptnpminstalljsencrypt2.引入jsencrypt//全局引入importJSEncryptfrom"jsencrypt";Vue.prototype.$jsEncrypt=JSEncrypt;//局部引入impor......
  • Python加密操作 对称加密/非对称加密
    安装包: pycryptodomehttps://pycryptodome.readthedocs.io/en/latest/src/installation.html#compiling-in-linux-ubuntu 1fromCrypto.HashimportSHA2562f......
  • Windows 10 读取bitlocker加密的硬盘出现参数错误怎么解决?
    我为了数据安全,用windows专业版的bitlocker加密了一个固态硬盘SSD做的移动硬盘(u盘同理),在家里电脑(windows10家庭版)打开的时候出现了参数错误即使密码输入正确还是这个错......
  • 数据库级别的MD5加密-2022-12-1
    MD5不可逆CREATETABLE`testmd5`(`id`INT(4)NOTNULL,`name`VARCHAR(20)NOTNULL,`pwd`VARCHAR(50)NOTNULL,PRIMARYKEY(`id`))ENGINE=INNODBDEF......
  • QuTrunk与MindSpore量子神经网络初探
    1、概述QuTrunk是启科量子开发和已经开源的一款量子编程框架软件产品,关于QuTrunk的详细介绍,用户可以访问启科的开发者社区站点详细了解,也可以进入github上此项目下进行查......