RSA加密---java和node兼容版(可直接复制使用)

目录

背景

实现

一、node代码

1、引入依赖

2、生成公钥和私钥

3、生成工具类

二、java代码

背景

本来项目的后端是node,里面登录接口用的是后端生成RSA公钥和私钥,公钥给前端网页用来加密,node后端解密,一切很和谐,突然要我上一个Android应用,结果java和node两边就是无法通配。

原因:默认的RSA加解密格式不一样,node默认的 'pkcs1_oaep', 而java中默认的是pkcs8

解决方法:两边都采用同一种模式就好了,这里我修改node为pkcs8.

实现

一、node代码

1、引入依赖

npm install node-rsa

2、生成公钥和私钥

const NodeRSA = require('node-rsa')

// 生成密文(和java通用版本)
var key = new NodeRSA({b: 1024})
var privateKey = key.exportKey('pkcs8-private')
var publicKey = key.exportKey('pkcs8-public-pem')

console.log(privateKey)
console.log(publicKey)

效果如下:

 

3、生成工具类

const NodeRSA = require('node-rsa')

var publicKey = '-----BEGIN PUBLIC KEY-----\n' +
  'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9WbdF8v9qt9u1nEbUnWLlDa/e\n' +
  '3gc67MhCgzRlwq+s7xVP6usKJbqB7FUIM0k1e7nx1eMgmpkL4y4sLjuWzms6OXo5\n' +
  'OFdb64RbdTKfo91bBVW9kWov8SiLL3/Y5NlEtG+uG0DWZSbBc73vPQlvUT/6Kuy9\n' +
  '7qFpCjXmyIDbHLUKQQIDAQAB\n' +
  '-----END PUBLIC KEY-----'

var privateKey = '-----BEGIN PRIVATE KEY-----\n' +
  'MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAL1Zt0Xy/2q327Wc\n' +
  'RtSdYuUNr97eBzrsyEKDNGXCr6zvFU/q6woluoHsVQgzSTV7ufHV4yCamQvjLiwu\n' +
  'O5bOazo5ejk4V1vrhFt1Mp+j3VsFVb2Rai/xKIsvf9jk2US0b64bQNZlJsFzve89\n' +
  'CW9RP/oq7L3uoWkKNebIgNsctQpBAgMBAAECgYB+KRK15oxL/KjFPpTrANptp0rx\n' +
  'AZprpmxf9K+qxabrYHkgwHNOVYkJHAAj8JfsrL1d5pbomFk01G9lPICzoGFMSaNA\n' +
  'kFlC15Td6/ERbDrIXjDjcggL8FfkWm1mb3UEZJsN/dLCclMDCEYnLMgfBKrj651+\n' +
  'Y9wvlqn0cltrIThbSQJBAO+U10ZHVnzO1A+FFN5NK7yoqGn/mOvwPIObEyASGznK\n' +
  'X0EpDcamt5giH7GrTaId24vILX1MpI+YamU3xzp3w/8CQQDKU6KUALBuKOLQrYW4\n' +
  '4wtdBiOSHsYbcMXJoXC+NAhwb6kz1aCnGRfxtzpVZmMtaoIzxuzmqdya09OTazyX\n' +
  'KjG/AkEAgqdM7wqgY9f3Va9hvgmfvHbNwWCeaKzOk4bSWz8EkfOHFuXomVj57oFN\n' +
  'f3rID4zw2b4E8LwHUjfwbdqJT51YyQJBAKsP/1tHIeRhqTNqIq9pN0hVUmnOnwzA\n' +
  'UlnhpyMJd0EpB1QOAKCG9NmnYyilQqE5dhA01kNHxn8ZLb9sYXQldp0CQQC1DOqN\n' +
  '5N8xx/k65MFgxIM/asyRhe6YCG7SCIAdyAau0S7v+Qf7R6tX4jWHWxhQfRl2dHKx\n' +
  'a3JZu+LOb8XwDxNQ\n' +
  '-----END PRIVATE KEY-----'

var key = new NodeRSA()
key.importKey(privateKey, 'pkcs8-private')
key.importKey(publicKey, 'pkcs8-public-pem')

// 加密
function encryption (data) {
  try {
    const dataEncry = key.encrypt(data, 'base64')
    // 返回结果
    return JSON.stringify({
      code: 200,
      data: dataEncry
    })
  } catch (e) {
    // 返回错误
    return JSON.stringify({
      code: 500,
      data: e
    })
  }
}

// 解密
function decryption (data) {
  try {
    const dataDecry = key.decrypt(data, 'utf8')
    // 返回结果
    return JSON.stringify({
      code: 200,
      data: dataDecry
    })
  } catch (e) {
    // 返回错误
    return JSON.stringify({
      code: 500,
      data: e
    })
  }
}

module.exports = {
  encryption,
  decryption
}

二、java代码

1、直接上工具类

注意:java代码中的公钥不需要开头和结尾的【-----BEGIN PUBLIC KEY-----】这个,只需要保留中间的密钥就好,且不要留有换行符【\n】。

import android.os.Build;

import androidx.annotation.RequiresApi;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * Rsa加解密工具(node后端通用版本)
 */
public class RsaUtil {

    /**
     * Rsa加密
     * @param data 需要加密的数据
     * @return 返回密文
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static String encrypt(String data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        byte[] dataBytes = data.getBytes();
        if (dataBytes.length > 214) throw new RuntimeException("不能一次性加密超过214字节的数据");
        String pubKey =
                "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9WbdF8v9qt9u1nEbUnWLlDa/e" +
                "3gc67MhCgzRlwq+s7xVP6usKJbqB7FUIM0k1e7nx1eMgmpkL4y4sLjuWzms6OXo5" +
                "OFdb64RbdTKfo91bBVW9kWov8SiLL3/Y5NlEtG+uG0DWZSbBc73vPQlvUT/6Kuy9" +
                "7qFpCjXmyIDbHLUKQQIDAQAB";
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] keyBytes = decoder.decode(pubKey);
        X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
        KeyFactory kf = KeyFactory.getInstance("RSA");
        PublicKey pk = kf.generatePublic(spec);

        byte[] cipherText;
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, pk);
        cipherText = cipher.doFinal(dataBytes);
        Base64.Encoder encoder = Base64.getEncoder();
        return encoder.encodeToString(cipherText);
    }

    /**
     * Rsa解密
     * @param data 需要解密的数据
     * @return 明文
     */
    @RequiresApi(api = Build.VERSION_CODES.O)
    public static String decrypt(String data) throws NoSuchAlgorithmException, InvalidKeySpecException, NoSuchPaddingException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {
        String privateKey =
                "MIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAL1Zt0Xy/2q327Wc" +
                        "RtSdYuUNr97eBzrsyEKDNGXCr6zvFU/q6woluoHsVQgzSTV7ufHV4yCamQvjLiwu" +
                        "O5bOazo5ejk4V1vrhFt1Mp+j3VsFVb2Rai/xKIsvf9jk2US0b64bQNZlJsFzve89" +
                        "CW9RP/oq7L3uoWkKNebIgNsctQpBAgMBAAECgYB+KRK15oxL/KjFPpTrANptp0rx" +
                        "AZprpmxf9K+qxabrYHkgwHNOVYkJHAAj8JfsrL1d5pbomFk01G9lPICzoGFMSaNA" +
                        "kFlC15Td6/ERbDrIXjDjcggL8FfkWm1mb3UEZJsN/dLCclMDCEYnLMgfBKrj651+" +
                        "Y9wvlqn0cltrIThbSQJBAO+U10ZHVnzO1A+FFN5NK7yoqGn/mOvwPIObEyASGznK" +
                        "X0EpDcamt5giH7GrTaId24vILX1MpI+YamU3xzp3w/8CQQDKU6KUALBuKOLQrYW4" +
                        "4wtdBiOSHsYbcMXJoXC+NAhwb6kz1aCnGRfxtzpVZmMtaoIzxuzmqdya09OTazyX" +
                        "KjG/AkEAgqdM7wqgY9f3Va9hvgmfvHbNwWCeaKzOk4bSWz8EkfOHFuXomVj57oFN" +
                        "f3rID4zw2b4E8LwHUjfwbdqJT51YyQJBAKsP/1tHIeRhqTNqIq9pN0hVUmnOnwzA" +
                        "UlnhpyMJd0EpB1QOAKCG9NmnYyilQqE5dhA01kNHxn8ZLb9sYXQldp0CQQC1DOqN" +
                        "5N8xx/k65MFgxIM/asyRhe6YCG7SCIAdyAau0S7v+Qf7R6tX4jWHWxhQfRl2dHKx" +
                        "a3JZu+LOb8XwDxNQ";
        //64位解码加密后的字符串
        Base64.Decoder decoder = Base64.getDecoder();
        byte[] inputByte = decoder.decode(data.getBytes("UTF-8"));
        //base64编码的私钥
        byte[] decoded = decoder.decode(privateKey);
        RSAPrivateKey priKey = (RSAPrivateKey) KeyFactory.getInstance("RSA").generatePrivate(new PKCS8EncodedKeySpec(decoded));
        //RSA解密
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA1AndMGF1Padding");
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        return new String(cipher.doFinal(inputByte));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/584412.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Flexible布局在Web前端开发中的实际应用

随着Web前端技术的不断发展,Flexible布局(弹性布局)已成为现代网页设计中不可或缺的一部分。它提供了一种高效、灵活的方式来组织和管理页面元素,使开发者能够轻松应对各种复杂的布局需求。本文将通过一个实际的应用案例来介绍Fle…

鸿蒙内核源码分析(汇编基础篇) | CPU在哪里打卡上班

本篇通过拆解一段很简单的汇编代码来快速认识汇编,为读懂鸿蒙汇编打基础.系列篇后续将逐个剖析鸿蒙的汇编文件. 汇编很简单 第一: 要认定汇编语言一定是简单的,没有高深的东西,无非就是数据的搬来搬去,运行时数据主要…

阿里云服务器(Ubuntu22)上的MySQL8更改为大小写不敏感

因为windows上默认的mysql8.0是大小写不敏感的,部署到服务器上之后发现ubuntu默认的是大小写敏感,所以为了不更改代码,需要将mysql数据库设置为大小写不敏感的。 !!!重要一定要做好数据库的备份&#xff0…

【Vue3】openlayers加载瓦片地图并手动标记坐标点

目录 一、创建Vue3项目 二、openlayers加载瓦片地图(引js文件版) 2.1 将以下的文件复制到public下 2.2 index.html引入ol脚本 2.3 删除项目自带的HelloWorld.vue,创建Map.vue 2.4 编码Map.vue 2.5 修改App.vue 2.6 启动项目测试 三、…

与Apollo共创生态:Apollo 7周年大会带给我的启发和心得

Apollo 7周年大会 前不久的Apollo 7周年大会,吸引到我这个对自动驾驶有着浓厚兴趣的开发者,真的精彩,受益匪浅。Apollo 7周年大会展示了Apollo在自动驾驶领域的创新成果,探讨自动驾驶技术的未来发展趋势,并推动自动驾…

关键技术自主可控,中国移动发布大云磐石DPU芯片,速率达400Gbps

4月28日,中国移动在2024算力网络大会上正式发布大云磐石DPU,该芯片带宽达到400Gbps,为国内领先水平,将应用于移动云新一代大云磐石DPU产品,实现关键技术自主可控。 据介绍,DPU是一种专注于数据处理的处理器…

Python多线程并不是真的并行执行

Python多线程虽然能够利用多个CPU核执行计算,但并不能真正执行多线程并行计算。因为在Python中,有一个全局解释锁(GlobalInterpreter Lock,GIL),该锁的存在使得在同一个时间只有一个线程执行任务&#xff0…

KKView远程控制2.0版本发布,TeamViewer面临巨大挑战

KKView远程控制2.0版本发布,TeamViewer面临巨大挑战 近日,备受瞩目的远程控制软件KKView发布了其全新2.0版本,KKView以其独特的创新性和用户友好的设计,为远程办公、远程培训等领域提供了更加高效、便捷的解决方案。 KKView远程…

DVWA靶场

DVWA是指Damn Vulnerable Web Application,是一个用于教育和训练网络安全人员的虚拟漏洞应用程序。DVWA模拟了一个包含了多种常见Web安全漏洞的虚拟环境,包括SQL注入、XSS攻击、CSRF攻击等等。通过使用DVWA,安全人员可以学习和实践各种Web安全…

c#数据库: 8.在窗体上显示学生信息

以上一章学生信息表为例,首先将查询的学生信息存储到数据集中,然后将数据集与数据显示控件绑定,从而实现学生信息在窗体上的显示 (1)创建一个名为StudentGridView的窗体应用程序,为窗体添加一个DataGridVi…

OSI 模型

OSI参考模型包括什么: OSI 参考模型分为七层从下往上分别是:物理层、数据链路层、网络层、传输层、会话层、表示层和应 用层 应用层 : 应用层是 OSI 标准模型的最顶层,是直接为应用进程提供服务的。其作用是在实现多个系统应用…

2024年十五届蓝桥杯省赛大学B组真题(Java完整版)

2024年十五届蓝桥杯省赛大学B组真题(Java) 前言: 赛后一直犹豫要不要对比赛进行复盘出个题解,拖到了现在,终于也是等到比赛结果出来,看到没有辜负个人期望成功取得省一,决定在国赛前对省赛进行…

【网络原理】UDP协议 | UDP报文格式 | 校验和 | UDP的特点 | 应用层的自定义格式

文章目录 一、UDP协议1.UDP的传输流程发送方接收方 2.UDP协议报文格式:长度受限校验和如何校验:CRC算法:循环冗余算法md5算法: 2.UDP的特点 二、开发中常见的自定义格式1.xml(古老)2.json(最流行…

nn.TransformerEncoderLayer详细解释,使用方法!!

nn.TransformerEncoderLayer nn.TransformerEncoderLayer 是 PyTorch 的 torch.nn 模块中提供的一个类,用于实现 Transformer 编码器的一个单独的层。Transformer 编码器层通常包括一个自注意力机制和一个前馈神经网络,中间可能还包含层归一化&#xff…

uniapp关于iconfont字体图标使用

1、打开[阿里巴巴矢量图标库](https://www.iconfont.cn/),选择需要的图标添加到购物车 2、点开购物车,将图标添加到项目 3、点开项目,点击下载至本地,会得到一个download.zip包 4、解压download包 5、将包里的iconfont.css和iconf…

正点原子[第二期]Linux之ARM(MX6U)裸机篇学习笔记-8.1--C语言LED驱动程序

前言: 本文是根据哔哩哔哩网站上“正点原子[第二期]Linux之ARM(MX6U)裸机篇”视频的学习笔记,在这里会记录下正点原子 I.MX6ULL 开发板的配套视频教程所作的实验和学习笔记内容。本文大量引用了正点原子教学视频和链接中的内容。…

Q1季度阿胶电商数据分析:某黑马品牌线上销售增长超1800%

作为滋补养三大宝之一,阿胶具有补血滋阴、润燥止血、益智健脑、缓延衰老、强筋健骨、提高免疫力等多种功效和作用。同时阿胶被誉为“补血神器”、“美容养颜”等,使得其备受市场欢迎。 根据鲸参谋数据显示,今年Q1季度,在综合电商…

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第15课-xcard方式跳转平行3D馆

【WEB前端2024】开源智体世界:乔布斯3D纪念馆-第15课-xcard方式跳转平行3D馆 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智…

记录一次大数据量接口优化过程

问题描述 记录一次大数据量接口优化过程。最近在优化一个大数据量的接口,是提供给安卓端APP调用的,因为安卓端没做分批次获取,接口的数据量也比较大,因为加载速度超过一两分钟,所以导致接口超时的异常,要让…

【C++干货基地】探索C++模板的魅力:如何构建高性能、灵活且通用的代码库(文末送书)

🎬 鸽芷咕:个人主页 🔥 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 引入 哈喽各位铁汁们好啊,我是博主鸽芷咕《C干货基地》是由我的襄阳家乡零食基地有感而发,不知道各位的…