MD5、RSA 和自定义签名的 Java 数据安全实战

news2024/12/23 13:06:51

前言

在现代的数字世界中,数据的安全性和完整性变得尤为重要。为了确保数据在传输和存储过程中不受到攻击,我们可以借助各种加密和签名技术来加强数据安全。本文将介绍如何使用 MD5、RSA 加密,以及如何自定义签名规则来保护数据的安全性。下面介绍如何结合 MD5、RSA 加密以及自定义签名规则,实现 Java 数据的安全传输和验证。

1、pom.xml依赖添加

<dependencies>
    <!-- Apache Commons Codec for MD5 hashing -->
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.15</version>
    </dependency>

    <!-- Bouncy Castle for RSA encryption -->
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.68</version>
    </dependency>
</dependencies>

2、MD5 加密和验证数据完整性

MD5(Message Digest Algorithm 5)是一种散列函数,用于生成输入数据的固定长度摘要。我们可以使用 MD5 对数据进行散列,并将摘要与原数据一同发送。接收方收到数据后同样进行 MD5 散列,然后比较摘要是否一致,以验证数据的完整性。下面是一个使用 Java 进行 MD5 加密和验证的示例:

import org.apache.commons.codec.digest.DigestUtils;

public class MD5Example {

    public static void main(String[] args) {
        // 要进行哈希的数据
        String data = "Hello, MD5!";
        
        // 自定义的盐值
        String salt = "mySecretSalt";

        // 生成 MD5 哈希值
        String hashedData = DigestUtils.md5Hex(data + salt);
        System.out.println("Hashed Data: " + hashedData);
    }
}

3、RSA 加密和解密敏感数据

RSA(Rivest–Shamir–Adleman)是一种非对称加密算法,使用一对公钥和私钥进行加密和解密。RSA 不仅用于数据的保护,还可以用于数字签名,以确保数据的完整性和身份验证。以下是一个使用 Java 进行 RSA 加密和解密的示例:

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;

import javax.crypto.Cipher;

public class RSAExample {

    public static void main(String[] args) throws Exception {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA", "BC");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String message = "Hello, RSA!";
        byte[] encrypted = encrypt(publicKey, message);
   		// 将字节数组转换为十六进制字符串(为了打印不乱码)
		String encryptedHex = bytesToHex(encrypted);
		System.out.println("Encrypted message: " + encryptedHex);
		
        String decrypted = decrypt(privateKey, encrypted);
        System.out.println("Decrypted message: " + decrypted);
    }
    
	/**
	 * 将字节数组转换为十六进制字符串的辅助方法
	 *
	 * @param bytes 要转换的字节数组
	 * @return 转换后的十六进制字符串
	 */
	public static String bytesToHex(byte[] bytes) {
	    StringBuilder result = new StringBuilder();
	    for (byte b : bytes) {
	        result.append(String.format("%02x", b));
	    }
	    return result.toString();
	}


    /**
     * 使用公钥加密敏感数据
     *
     * @param publicKey 用于加密的公钥
     * @param message   要加密的数据
     * @return 加密后的数据
     * @throws Exception 加密过程中的异常
     */
    public static byte[] encrypt(PublicKey publicKey, String message) throws Exception {
        // 使用 RSA/ECB/PKCS1Padding 和 Bouncy Castle 提供的加密方式
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(message.getBytes());
    }

    /**
     * 使用私钥解密加密的数据
     *
     * @param privateKey 用于解密的私钥
     * @param encrypted  加密的数据
     * @return 解密后的数据
     * @throws Exception 解密过程中的异常
     */
    public static String decrypt(PrivateKey privateKey, byte[] encrypted) throws Exception {
        // 使用 RSA/ECB/PKCS1Padding 和 Bouncy Castle 提供的加密方式
        Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encrypted);
        return new String(decryptedBytes);
    }
}

请添加图片描述

4、 自定义签名规则加强数据验证

除了 MD5 和 RSA,我们还可以使用自定义签名规则来加强数据验证。通过在数据中添加私密信息(盐)并生成签名,我们可以验证数据的完整性和发送方的合法性。以下是一个简单的示例:

import org.apache.commons.codec.digest.DigestUtils;

public class CustomSignatureExample {

    public static void main(String[] args) {
        String data = "Hello, Custom Signature!";
        String salt = "myCustomSalt";

        // 生成签名
        String signature = generateSignature(data, salt);
        System.out.println("Generated Signature: " + signature);

        // 验证签名
        boolean isValid = verifySignature(data, salt, signature);
        System.out.println("Signature Verification: " + isValid);
    }

    /**
     * 生成自定义签名
     *
     * @param data 要签名的数据
     * @param salt 自定义盐值
     * @return 生成的签名
     */
    public static String generateSignature(String data, String salt) {
        // 使用 Apache Commons Codec 库中的 md5Hex 方法计算 MD5 散列
        return DigestUtils.md5Hex(data + salt);
    }

    /**
     * 验证自定义签名
     *
     * @param data      原始数据
     * @param salt      自定义盐值
     * @param signature 要验证的签名
     * @return 是否验证通过
     */
    public static boolean verifySignature(String data, String salt, String signature) {
        // 重新生成签名,并与传入的签名比较
        String generatedSignature = generateSignature(data, salt);
        return generatedSignature.equals(signature);
    }
}

5、数据安全综合实例

在实际应用中,我们可以综合使用以上技术来实现数据的安全传输。例如,可以使用 RSA 对敏感数据进行加密,然后使用 MD5 对加密后的数据生成摘要,同时使用自定义签名规则对数据进行签名。这样的组合可以在保护数据完整性的同时确保数据的机密性。综合示例代码:

import java.security.*;
import javax.crypto.Cipher;
import org.apache.commons.codec.digest.DigestUtils;

public class DataSecurityExample {

    public static void main(String[] args) throws Exception {
        // 生成 RSA 密钥对
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();

        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        // 使用 RSA 加密数据
        String sensitiveData = "This is a secret message!";
        byte[] encryptedData = encrypt(publicKey, sensitiveData);

        // 生成加密数据的 MD5 哈希
        String md5Hash = DigestUtils.md5Hex(encryptedData);

        // 生成自定义签名
        String salt = "mySecretSalt";
        String signature = generateSignature(md5Hash, salt);

        // 模拟数据传输和验证
        boolean isValid = verifySignature(md5Hash, salt, signature);
        if (isValid) {
            String decryptedData = decrypt(privateKey, encryptedData);
            System.out.println("Decrypted Data: " + decryptedData);
        } else {
            System.out.println("Data integrity compromised!");
        }
    }

    /**
     * 使用公钥加密数据
     */
    public static byte[] encrypt(PublicKey publicKey, String data) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        return cipher.doFinal(data.getBytes());
    }

    /**
     * 使用私钥解密数据
     */
    public static String decrypt(PrivateKey privateKey, byte[] encryptedData) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedData);
        return new String(decryptedBytes);
    }

    /**
     * 生成自定义签名
     */
    public static String generateSignature(String data, String salt) {
        return DigestUtils.md5Hex(data + salt);
    }

    /**
     * 验证自定义签名
     */
    public static boolean verifySignature(String data, String salt, String signature) {
        String generatedSignature = generateSignature(data, salt);
        return generatedSignature.equals(signature);
    }
}

通过综合使用 MD5、RSA 加密以及自定义签名规则,我们可以实现数据的安全传输和验证。这些技术在现代数据通信中发挥着重要作用,保护着数据的隐私和完整性。在实际应用中,根据具体场景的需求,我们可以选择适合的加密和签名方式,以达到最优的数据安全效果。

总结

本文介绍了如何结合 MD5、RSA 加密以及自定义签名规则,实现 Java 数据的安全传输和验证。通过使用 MD5 散列保证数据完整性,RSA 加密确保敏感数据的保密性,以及自定义签名规则增强数据验证,我们可以构建出强大而灵活的数据安全机制。

在实际开发中,不同的场景和需求可能需要不同的数据安全方案。因此,在选择适合的加密和签名方法时,需要综合考虑数据保护级别、性能要求以及实施复杂度等因素。

通过本文提供的示例代码和解释,您可以开始在您的 Java 应用程序中应用 MD5、RSA 和自定义签名技术,从而确保您的数据在传输和存储过程中得到充分的保护。无论是通信过程中的数据传输,还是数据存储在服务器上,都可以通过合理的数据安全措施来应对潜在的风险,确保数据的安全性和可靠性。

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

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

相关文章

ISO 21202:2020 智能交通系统 - 部分自动变道系统 (PALS) - 功能/操作要求和测试规程

​ 介绍 一般来说,车辆配备的驾驶辅助系统和自动驾驶系统可减轻驾驶员的负担,有助于安全驾驶。就变道操作而言,有许多驾驶员并不擅长变道,为了辅助这类驾驶员,部分自动变道系统(PALS)可根据驾驶员的要求,在驾驶员的监督下,在禁止非机动车和行人通行、有明显车道标记的…

C#中的委托

目录 概述&#xff1a; 举例&#xff1a;​ 总结: 概述&#xff1a; 中文的角度来说:指的是把事情托付给别人或别的机构(办理)&#xff0c;造个句子&#xff1a;别人委托的事情&#xff0c;我们一定要尽力而为&#xff0c;不遗余力的去办成。 在C#中&#xff0c;委托是一种…

TCP/IP协议组

TCP/IP通信协议是目前最完整、使用最广泛的通信协议。它的魅力在于可使不同硬件结构、不同操作系统的计算机相互通信。TCP/IP协议既可用于广域网&#xff0c;也可用于局域网&#xff0c;它是Internet/Intranet的基石。TCP/IP通信协议事实上是一组协议。 TCP/IP协议可分为5层也可…

图像处理的未来:揭秘扫描全能王的AI驱动创新

&#x1f935;‍♂️ 个人主页&#xff1a;艾派森的个人主页 ✍&#x1f3fb;作者简介&#xff1a;Python学习者 &#x1f40b; 希望大家多多支持&#xff0c;我们一起进步&#xff01;&#x1f604; 如果文章对你有帮助的话&#xff0c; 欢迎评论 &#x1f4ac;点赞&#x1f4…

LeetCode235. 二叉搜索树的最近公共祖先

235. 二叉搜索树的最近公共祖先 文章目录 [235. 二叉搜索树的最近公共祖先](https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-search-tree/)一、题目二、题解方法一&#xff1a;递归方法二&#xff1a;迭代 一、题目 给定一个二叉搜索树, 找到该树中两个指定…

java八股文面试——String StringBuilder StringBuffer

String类型定义&#xff1a; final String 不可以继承 final char [] 不可以修改 String不可变的好处&#xff1a; hash值只需要算一次&#xff0c;当String作为map的key时&#xff0c; 不需要考虑hash改变 天然的线程安全 知识来源&#xff1a; 【基础】String、StringB…

安卓手机录屏app合集,总有一种适合你

在现代生活中&#xff0c;录屏已经变得越来越重要。它可以帮助人们记录并分享他们的屏幕内容。在安卓手机上&#xff0c;有很多应用程序可以帮助您进行屏幕录制。本文将介绍一些最好的安卓手机录屏应用程序&#xff0c;以及一些有关录屏技巧。 录屏工具&#xff1a; 迅捷录屏大…

通达信接口开发大全(一)

通达信软件的接口开发主要可以分为以下几个方面&#xff1a; 行情接口&#xff1a;通达信提供行情订阅和实时数据查询接口&#xff0c;可以获取市场行情数据。开发者通过这些接口获取股票、期货、外汇等市场的实时行情数据&#xff0c;包括价格、成交量、买卖盘等。 交易接口&…

博弈论简介

目录 博弈分类 合作与非合作博弈&#xff1a; 同时与顺序博弈&#xff1a; 完全信息与不完全信息博弈&#xff1a; 零和与非零和博弈&#xff1a; 囚徒困境的例子 纳什平衡 代码示例 博弈论是一个数学分支&#xff0c;研究多个理性决策者之间的战略互动。它的主要目的是…

Kafka 集群搭建过程

前言 跟着尚硅谷海哥文档搭建的Kafka集群环境&#xff0c;在此记录一下&#xff0c;侵删 注意&#xff1a;博主在服务器上搭建环境的时候使用的是一个服务器&#xff0c;所以这篇博客可能会出现一些xsync分发到其他服务器时候的错误&#xff0c;如果你在搭建的过程中出现了错…

CKZF-D60170、CKZF-D70190、CKZF-D80210单向离合器

CKZF-C30100、CKZF-C35110、CKZF-C40125、CKZF-C45130、CKZF-C50150、CKZF-C55160、CKZF-C60170、CKZF-C70190、CKZF-C80210、CKZF-C90230、CKZF-C100270、CKZF-C130310、CKZF-B30100、CKZF-B35110、CKZF-B40125、CKZF-B45130、CKZF-B50150、CKZF-B55160、CKZF-B60170、CKZF-B7…

Java课题笔记~ 什么是跨域?

什么是跨域&#xff1f; 浏览器从一个域名的网页去请求另一个域名的资源时&#xff0c;域名、端口、协议任一不同&#xff0c;都是跨域。 域名&#xff1a; 主域名不同 百度一下&#xff0c;你就知道 -->新浪网 子域名不同 http://www.666.baidu.com/index.html -->htt…

原生js获取今天、昨天、近7天的时间(年月日时分秒)

有的时候我们需要将今天,昨天,近7天的时间(年月日时分秒)作为参数传递给后端,如下图: 那怎么生成这些时间呢?如下代码里,在methods里的toDay方法、yesterDay方法、weekDay方法分别用于生成今天、昨天和近7天的时间: <template><div class="box"&…

springBoot是如何实现自动装配的

目录 1 什么是自动装配 2 Spring自动装配原理 2.1 SpringBootConfiguration ​编辑 2.2 EnableAutoConfiguration 2.2.1 AutoConfigurationPackage 2.2.2 Import({AutoConfigurationImportSelector.class}) 2.3 ComponentScan 1 什么是自动装配 自动装配就是将官方写好的的…

电脑c盘满了怎么办,使用硬盘专家一件解决!

下载硬盘专家后&#xff0c;点击释放C盘系统空间&#xff0c;就可以节省出很多空间&#xff0c;win10系统一般节省出20G都是正常的&#xff0c;因为win10在很多地方都恶意占用磁盘空间&#xff0c;比如一些大型的垃圾&#xff0c;都没有及时清理&#xff0c;就算你使用杀毒软件…

接口和抽象类的区别(一看就懂)

目录 1 抽象类作用 2 接口和抽象类区别 1 抽象类作用 接口&#xff1a;接口其实可以看做是多态的一种体现&#xff08;多态&#xff1a;一种行为的多种表现形态&#xff09;不妨想想平时你自己在service中写是不是定义了一个service接口&#xff0c;然后用一个serviceImpl实…

无代码集成飞书连接更多应用

场景描述&#xff1a; 基于飞书开放平台能力&#xff0c;无代码集成飞书连接更多应用&#xff0c;打通数据孤岛。通过Aboter可轻松搭建业务自动化流程&#xff0c;实现多个应用之间的数据连接。 支持包括飞书事件监听和接口调用的能力&#xff1a; 事件监听&#xff1a; 用…

Java“牵手”根据商品ID获取1688商品评论数据方法,1688API实现批量商品评论内容数据抓取示例

1688商城是一个网上购物平台&#xff0c;售卖各类商品&#xff0c;包括服装、鞋类、家居用品、美妆产品、电子产品等。要获取1688商品详情页面评价内容数据&#xff0c;您可以通过开放平台的接口或者直接访问1688商城的网页来获取商品详情信息内的评论数据。以下是两种常用方法…

netstat: command not found

执行&#xff1a; cd /etc/yum.repos.d/ sed -i s/mirrorlist/#mirrorlist/g /etc/yum.repos.d/CentOS-* sed -i s|#baseurlhttp://mirror.centos.org|baseurlhttp://vault.centos.org|g /etc/yum.repos.d/CentOS-* wget: command not found 执行&#xff1a;&#xff08;安装…

Java版企业电子招投标采购系统源码之首页设计 tbms

​ 功能描述 1、门户管理&#xff1a;所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含&#xff1a;招标公告、非招标公告、系统通知、政策法规。 2、立项管理&#xff1a;企业用户可对需要采购的项目进行立项申请&#xff0c;并提交审批&#xff0c;查…