Java实现基于RSA的数字签名

news2024/12/24 11:07:05

加密与数字签名的区别

1、加密保证了数据接受方的数据安全性。加密的作用是防止泄密。

2、签名保证了数据发送方的数据安全性。签名的作用是防止篡改。

数字签名的应用

问题:在比特币中,怎么证明这个交易是你发布的?

这是就需要用到数字签名,数字签名大概可已描述为:用私钥加密,用公钥解密。发布一条交易信息:“我给xxx转了0.2个比特币”,将这条消息用自己的私钥加密,再发布出去,大众在收到这条消息后,用我的公钥验签,验证成功则说明是我发布的交易。

签名的过程与加密相反。

代码

package RSA;

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

import java.io.BufferedReader;
import java.io.FileReader;
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;

/**
 * @author WuYongheng
 * @date 2022/11/22
 * @description 数字签名  RSA
 */
public class RsaSignature {

    //数字签名 - 签名验证算法
    private static final String SIGNATRUE_ALGORITHM = "MD5withRSA";
    //数字签名 - RSA算法
    private static final String KEY_ALGORITHM = "RSA";
    //私钥
    private static final String PRIVATEKEY = "RSAPrivateKey";
    //公钥
    private static final String PUBLICKEY = "RSAPublicKey";

    /**
     * RSA长度
     * 默认是 1024
     * 必须是 64的倍数
     * 范围:512 - 65536
     */
    private static final int KeySize = 512; // 512 位 2进制,128 位 16进制

    /**
     * 初始化
     *
     * @return map
     * @throws Exception
     */
    public static Map<String, Object> initKey() throws Exception {
        //实例化,生成器
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(KEY_ALGORITHM);
        //初始化
        keyPairGenerator.initialize(KeySize);
        //获取公私钥对
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        //获取私钥
        RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
        //获取公钥
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(PRIVATEKEY, privateKey);
        map.put(PUBLICKEY, publicKey);
        return map;
    }

    /**
     * 取得公钥
     *
     * @param map
     * @return byte[]
     */
    public static byte[] getPublicKey(Map<String, Object> map) {
        PublicKey publicKey = (PublicKey) map.get(PUBLICKEY);
        return publicKey.getEncoded();
    }

    /**
     * 取得私钥
     *
     * @param map
     * @return byte[]
     */
    public static byte[] getPrivateKey(Map<String, Object> map) {
        PrivateKey privateKey = (PrivateKey) map.get(PRIVATEKEY);
        return privateKey.getEncoded();
    }

    /**
     * 私钥加密
     *
     * @param source 数据
     * @param key    私钥
     * @return 签名
     * @throws Exception
     */
    public static String sign(String source, byte[] key) throws Exception {
        byte[] data = source.getBytes("utf-8");

        // 取得私钥
        PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);

        // 生成私钥
        PrivateKey privateKey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);

        //新增: 实例化 签名对象
        Signature signature = Signature.getInstance(SIGNATRUE_ALGORITHM);
        //初始化 私钥
        signature.initSign(privateKey);
        //更新签名
        signature.update(data);
        byte[] enSign = signature.sign();

        return Base64.encodeBase64String(enSign);
    }

    /**
     * 校验
     *
     * @param source  源数据
     * @param key     公钥
     * @param signStr 已签名的数据
     * @return true or false
     * @throws Exception
     */
    public static boolean verify(String source, byte[] key, String signStr) throws Exception {
        // 还原即将 解密的 数据源
        byte[] data = source.getBytes("utf-8");
        // 还原已签名数据
        byte[] signData = Base64.decodeBase64(signStr);

        // 取得公钥
        X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key);
        KeyFactory keyFactory = KeyFactory.getInstance(KEY_ALGORITHM);
        // 生成公钥
        PublicKey publicKey = keyFactory.generatePublic(x509EncodedKeySpec);

        //新增: 实例化 签名对象
        Signature signature = Signature.getInstance(SIGNATRUE_ALGORITHM);
        //初始化 校验公钥
        signature.initVerify(publicKey);
        //更新签名
        signature.update(data);
        //验证
        return signature.verify(signData);
    }

    public static void main(String[] args) throws Exception {
        Map<String, Object> keyMap = initKey();
        byte[] privateKey = getPrivateKey(keyMap);
        byte[] publicKey = getPublicKey(keyMap);
        System.out.println("获取的私钥:" + Base64.encodeBase64String(privateKey));
        System.out.println("获取的公钥:" + Base64.encodeBase64String(publicKey));

        String source = "";
        //需要签名文件的内容
        String fileName = "D:\\code\\aaa.txt";
        try (BufferedReader br = new BufferedReader(new FileReader(fileName))) {
            String line;
            while ((line = br.readLine()) != null) {
                System.out.println("文件内容是: " + line);
                source = line;
            }
        }
        System.out.println("需要签名的文件内容是: " + source);
        String sign = sign(source, privateKey);
        System.out.println("签名后:" + sign);
        boolean flat = verify(source, publicKey, sign);
        System.out.println("校验结果:" + flat);
    }
}


效果

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

客户关系应该如何管理?

网络经过十多年的产业发展&#xff0c;中国的网络用户已经超过了8亿&#xff0c;网络也渐渐改变了盲目的商业价值追求&#xff0c;趋于稳定理性&#xff0c;已经开始向着多个路径全面性产业发展。网络上出现了各式各样的网络营销方式&#xff0c;如邮件网络营销、广告行业、浏览…

【python实战】朋友因股票亏了,很惨常愤恨不平,当天我就分析出原因:怎么做到的?(听说关注我的人会暴富)

导语 有温度 有深度 有广度 就等你来关注哦~ 所有文章完整的素材源码都在&#x1f447;&#x1f447; 粉丝白嫖源码福利&#xff0c;请移步至CSDN社区或文末公众hao即可免费。 对于大部分股票投资者来说&#xff0c;一年能拿住翻倍的股票就实属不易。一年10倍&#xff0c;甚至…

生物素标记肽Biotin-εAhx-GLKLRFEFSKIKGEFLKTPEVRFRDIKLKDN

编号: 162943中文名称: 生物素标记肽Biotin-εAhx-GLKLRFEFSKIKGEFLKTPEVRFRDIKLKDN英文名: Biotin-εAhx-Gly-Leu-Lys-Leu-Arg-Phe-Glu-Phe-Ser-Ly英文同义词: Biotinyl-LC-hCAP-18 (134-170) (Scrambled), Biotinyl-LC-Cationic Antimicrobial Protein 18 (134-170) (human) …

hi mate, lets recall the bloody “JOIN“

补补数据库基础 上图中&#xff0c;表A的记录是123&#xff0c;表B的记录是ABC&#xff0c;颜色表示匹配关系。返回结果中&#xff0c;如果另一张表没有匹配的记录&#xff0c;则用null填充。 注意&#xff1a;多表连接查询会比直接使用自带的API查询表中的一个属性&#xff0…

基于STM32单片机的智能窗帘系统

本设计是基于STM32单片机的智能窗帘系统&#xff0c;主要实现以下功能&#xff1a; 1、 定时模式&#xff1a;早上&#xff08;7:00&#xff09;自动打开窗帘&#xff0c;晚上&#xff08;19&#xff1a;00&#xff09;自动关闭窗帘。 2、 手动模式&#xff1a;通过按键实现对…

处理 S4过账时的错误:“更正统一日记账分类账的定制设置”

目录 一、问题起因 二、问题分析​​​​​​​ 三、解决方法: 一、问题起因 在一个新配置的S4系统做FI凭证出现了如下报错&#xff1a; 点开后&#xff0c;报错显示如下&#xff1a; 更正统一日记账分类账的定制设置 消息号 FINS_ACDOC_CUST201 诊断 通用日记账的分类账…

SCADA系统在石油炼制行业的应用:如何实现石油炼制过程实时数据采集与监控?

一、应用背景 随着经济的逐步发展&#xff0c;企业开始关注基础技术和生产质量的提升。其中&#xff0c;作为基础工业项目的石油炼制企业需要对整体技术进行集中的整合&#xff0c;强化基础动态生产调度以及系统化的电子商务结构&#xff0c;才能提升整个行业的市场竞争力。 …

抢跑“补盲”风口,纯固态激光雷达上车面临哪些挑战?

未来两年&#xff0c;激光雷达市场高速发展的同时&#xff0c;来自市场的需求也逐渐清晰化。 高工智能汽车研究院预测数据显示&#xff0c;预计2025年前装标配激光雷达交付将有望达到200万颗/年的规模。其中&#xff0c;面向私人消费市场的车型&#xff0c;将主要以1颗前向、2…

“如何实现高效的应用交付”鲁班会开发者训练营厦门站进行时

摘要&#xff1a;2022年11月18日&#xff0c;来自厦门创新中心的40余位开发者&#xff0c;齐聚华为云鲁班会开发者训练营厦门站&#xff0c;与华为云技术大咖共同探讨技术未来&#xff0c;落地应用交付。为了抓住新时代IT技术脉搏&#xff0c;一同探讨企业数字化转型中面临的种…

Qt富文本处理

一、富文本文档结构 文本文档由 QTextDocument 类表示&#xff0c;该类包含有关文档内部表示、结构的信息&#xff0c;并跟踪修改以提供撤消/回撤功能。 1.1、基本结构 每个文档始终包含一个根框架&#xff0c;并且始终包含至少一个文本块。 框架/表格总是由文档中的文本块…

16.PyQt5中的事件系统之事件(QEvent)的传递(分发)和处理

PyQt5中的事件系统之事件(QEvent)的传递(分发)和处理 使用Qt编程&#xff0c;几乎不用考虑事件&#xff0c;因为当产生某种事件时&#xff0c;Qt窗口部件都会发射一个相应的信号&#xff08;即Qt会把事件转换为一个对应的信号&#xff09;&#xff0c;比如按钮被按下时&#x…

Servlet是什么?怎么使用?

前言&#xff1a; 服务器里面资源分为动态资源和静态资源 动态资源&#xff1a;Servlet、Jsp 静态资源&#xff1a;HTML、CSS、JS 一、概念 1.什么是servlet&#xff1f; 本质上是一个接口&#xff0c;提供了规范。是java提供的一门动态的web资源开发技术。 2.servlet体…

【C++】string类超详细解析

参考文献&#xff1a;C标准库官网 前言&#xff1a;在C/C的学习过程当中一定一定要多刷题&#xff0c;牛客网作为国内内容超级丰富的IT题库&#xff0c;尤其是它的C、C&#xff0c;有从入门到大厂真题&#xff0c;而且大部分的考试题目也是从中抽取&#xff0c;还有很多面经&am…

智慧职教解决方案-最新全套文件

智慧职教解决方案-最新全套文件一、建设背景二、建设思路三、建设方案四、获取 - 智慧职教全套最新解决方案合集一、建设背景 职业教育目前存在的问题&#xff1a; 发展理念相对落后国际化程度不高基本制度不健全层次结构不合理基础能力相对薄弱社会吸引力不强行业企业参与不…

20221121将行车记录仪记录的MJPEG格式的AVI片段合并的MKV转换为MP4

20221121将行车记录仪记录的MJPEG格式的AVI片段合并的MKV转换为MP4 2022/11/21 21:51 &#xff08;一&#xff09; 缘起&#xff0c;用行车记录仪录制的爬拉胡线&#xff08;惠州大南山&#xff09;的AVI视频&#xff0c;一个片段5分钟。 使用mkvtoolnix-gui将AVI合并成为MKV视…

垂直定位系统实验平台

系统概述 本系统由控制系统和被控对象两部分组成&#xff0c;可根据课程需要进行双轴机构的轴数增减和循序渐进的运动控制实训。 控制系统部分由水平轴执行机构、人机界面机构、电源机构、驱动元件与控制器等组成。控制方式&#xff1a;人机界面模拟控制。 控制对象部分由水…

如何制作传统节日网站(纯HTML代码)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

clean-label backdoor attacks 论文笔记

#论文笔记# 1. 论文信息 论文名称Clean-Label Backdoor Attacks作者Alexander Turner(MIT)会议/出版社ICLR 2019pdf本地pdf 在线pdf代码trojanzoo-clean-label**** Label-Consistent其他这篇文章和 Label-Consistent Backdoor Attacks 基本相同 简介&#xff1a;这篇文章是最…

Java内部类解析

作者&#xff1a;~小明学编程 文章专栏&#xff1a;JavaSE基础 格言&#xff1a;目之所及皆为回忆&#xff0c;心之所想皆为过往 目录 什么是内部类 静态内部类 静态内部类访问外部类的规则 外部类访问静态内部类的规则 实例化静态内部类 非静态内部类 内部类访问外部类…

【网安神器篇】——hydra爆破工具

作者名&#xff1a;Demo不是emo 主页面链接&#xff1a;主页传送门创作初心&#xff1a;舞台再大&#xff0c;你不上台&#xff0c;永远是观众&#xff0c;没人会关心你努不努力&#xff0c;摔的痛不痛&#xff0c;他们只会看你最后站在什么位置&#xff0c;然后羡慕或鄙夷座右…