Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java安全编程:公钥加密和私钥签名的实践指南

Java安全编程:公钥加密和私钥签名的实践指南

作者头像
陆业聪
发布于 2024-10-28 04:11:17
发布于 2024-10-28 04:11:17
34001
代码可运行
举报
运行总次数:1
代码可运行

在数字通信和数据保护领域,非对称加密技术扮演着至关重要的角色。这种技术涉及两种关键操作:使用公钥进行加密和使用私钥进行签名。这两种操作虽然使用相似的技术,但它们的目的、安全需求和实现方式却大相径庭。

一、公钥加密:确保信息机密性

公钥加密的主要目的是保护信息的机密性,确保只有授权的接收者能够读取信息。在这种机制中,每个参与者都拥有一对密钥:一个公开的公钥和一个私有的私钥。公钥对外公开,任何人都可以使用它来加密信息;而私钥则必须严格保密,只有密钥的持有者才能解密由其对应公钥加密的信息。

例如,当小红需要安全地发送信息给小明时,她会使用小明的公钥进行加密。由于只有小明拥有相应的私钥,因此只有他能解密这条信息。这种方式确保了即使信息在传输过程中被第三方截获,没有小明的私钥,他们也无法阅读信息内容。

二、私钥签名:验证信息完整性和来源

与公钥加密不同,数字签名的目的是保证信息的完整性和认证性。这意味着接收方不仅可以确认信息未被篡改,还能验证信息的发送者身份。在签名过程中,发送者使用自己的私钥对信息或其摘要(通常通过哈希函数生成)进行签名。

举个例子,当小红向小明发送一条消息时,她会使用自己的私钥对消息进行签名,并将签名连同原始消息一起发送给小明。小明收到消息后,可以使用小红的公钥来验证签名。如果签名验证成功,这表明消息确实由小红发送,并且在传输过程中未被篡改。

三、RSA-PSS 签名方案

3.1 RSA-PSS 介绍

在数字签名的过程中,特别是在使用如 RSA PSS 这样的高级签名方案时,各个参数的选择和配置对于确保签名的安全性和有效性至关重要。RSA-PSS 是一种公钥加密技术中的签名方案,它提供了比传统的 PKCS#1 v1.5 签名方案更高的安全性。

3.2 RSA-PSS 签名运算过程

Java中可以使用 PSSParameterSpec 类用于配置 RSA-PSS 签名方案的参数。这个类定义了 RSA-PSS 签名方案的参数规范,该方案在 PKCS#1 v2.1 标准中有定义,我们可以通过以下链接查看详细信息:PKCS#1 v2.1。

PKCS#1 标准中的 ASN.1 定义如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
RSASSA-PSS-params ::= SEQUENCE {
  hashAlgorithm      [0] OAEP-PSSDigestAlgorithms  DEFAULT sha1,
  maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
  saltLength         [2] INTEGER  DEFAULT 20,
  trailerField       [3] INTEGER  DEFAULT 1
}

下面详细解释每个参数的作用以及它们在签名过程中的具体运算:

3.2.1 hashAlgorithm
  • 作用hashAlgorithm 是用于生成消息摘要的哈希算法。消息摘要是原始数据经过哈希处理后的结果,它提供了一种固定长度的、代表原始数据的值。这个摘要是签名算法的输入之一,确保了数据的完整性,因为任何对数据的微小修改都会导致生成一个完全不同的哈希值。
  • 运算过程:首先,原始数据通过哈希算法处理,生成一个固定长度的哈希值(消息摘要)。例如,使用 SHA-256 哈希算法处理数据 "Hello, world!",可能得到一个256位的哈希值。
3.2.2 maskGenAlgorithm
  • 作用maskGenAlgorithm 是掩码生成函数(MGF),用于在签名过程中生成一个与消息摘要长度相同的掩码。这个掩码通过与消息摘要进行异或操作,增加了签名的随机性和安全性。
  • 运算过程:掩码生成函数使用相同的哈希算法来生成一个与消息摘要长度相同的掩码。然后,这个掩码与消息摘要进行异或操作,结果是一个“掩码化”的摘要。
3.2.3 saltLength
  • 作用:盐是一个随机生成的数据片段,其长度由 saltLength 指定。在签名过程中,盐被添加到消息摘要之后,用于增加签名的唯一性和安全性。
  • 运算过程:生成一个随机的盐(例如20字节长),然后将这个盐附加到消息摘要的末尾。这个组合(消息摘要+盐)再进行进一步的处理,如与掩码进行异或操作。
3.2.4 trailerField
  • 作用trailerField 是一个标识符,通常用于标记签名的结尾,确保签名格式的正确解析。它帮助解析过程识别签名的结构,确保数据的正确解码。
  • 运算过程:在签名数据的最后添加 trailerField(通常是一个预定义的值,如1),这样接收方在验证签名时可以识别并正确处理签名数据。

3.3 签名过程示例

假设我们有一段数据 "Hello, world!",我们需要对其进行签名:

  1. 生成消息摘要:使用 SHA-256 对 "Hello, world!" 进行哈希,得到一个256位的哈希值。
  2. 生成盐:随机生成一个20字节的盐。
  3. 附加盐:将盐附加到消息摘要的末尾。
  4. 生成掩码:使用 MGF1(基于SHA-256)生成一个与消息摘要+盐的长度相同的掩码。
  5. 应用掩码:将掩码与消息摘要+盐进行异或操作。
  6. 添加 trailerField:在最后添加 trailerField
  7. 私钥加密:使用私钥对上述结果进行加密,生成签名。

这个过程确保了签名的安全性和唯一性,使得任何对数据或签名的未授权修改都能被检测到。

四、Java中的实现示例

为了实现上述的加密和签名功能,我们可以利用Java的java.security包。以下是两个简单的示例,展示如何使用Java进行公钥加密和私钥签名。

4.1 示例1: 使用公钥加密和私钥解密

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PublicKey;
import java.security.PrivateKey;
import javax.crypto.Cipher;

public class PublicKeyEncryption {
    public static void main(String[] args) throws Exception {
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        keyPairGenerator.initialize(2048);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();

        String message = "Hello, this is a secret message!";
        byte[] messageBytes = message.getBytes();

        // 使用公钥加密
        Cipher cipher = Cipher.getInstance("RSA");
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(messageBytes);
        System.out.println("Encrypted Message: " + new String(encryptedBytes));

        // 使用私钥解密
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        System.out.println("Decrypted Message: " + new String(decryptedBytes));
    }
}

4.2 示例2: 使用私钥签名和公钥验签

在 Java 中使用 RSA PSS 签名机制时,可以通过 PSSParameterSpec 类来指定签名和验证过程中使用的参数。下面的示例展示了如何使用 SHA256withRSA/PSS 算法组合进行签名和验证。这个示例包括了设置 PSSParameterSpec 参数,使用私钥进行签名,以及使用公钥进行签名验证。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.MGF1ParameterSpec;
import java.security.spec.PSSParameterSpec;

public class RSAPSSSignatureExample {
    public static void main(String[] args) {
        try {
            // 1. 生成 RSA 密钥对
            KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
            KeyPair keyPair = keyPairGenerator.generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();

            // 2. 设置 PSS 参数
            PSSParameterSpec pssParameterSpec = new PSSParameterSpec(
                "SHA-256",
                "MGF1",
                MGF1ParameterSpec.SHA256,
                32,  // 盐的长度
                1    // trailer field
            );

            // 3. 初始化签名对象
            Signature signature = Signature.getInstance("SHA256withRSA/PSS");
            signature.setParameter(pssParameterSpec);
            signature.initSign(privateKey);

            // 4. 提供数据给签名对象
            String message = "Hello, world!";
            signature.update(message.getBytes());

            // 5. 生成数字签名
            byte[] digitalSignature = signature.sign();
            System.out.println("Digital Signature: " + bytesToHex(digitalSignature));

            // 6. 验证签名
            signature.initVerify(publicKey);
            signature.update(message.getBytes());
            boolean isCorrect = signature.verify(digitalSignature);
            System.out.println("Signature correct: " + isCorrect);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 辅助方法,用于将字节转换为十六进制字符串
    private static String bytesToHex(byte[] bytes) {
        StringBuilder sb = new StringBuilder();
        for (byte b : bytes) {
            sb.append(String.format("%02X ", b));
        }
        return sb.toString();
    }
}

注意,盐长度的一致性是确保签名验证成功的关键。如果签名时和验证时使用的盐长度不一致,即使其他所有参数都相同,签名验证也会失败。盐在加密过程中增加了额外的随机性,不匹配的盐长度会导致生成的签名完全不同。

代码解释

  1. 生成密钥对:使用 KeyPairGenerator 生成 RSA 密钥对,密钥长度为 2048 位。
  2. 配置 PSS 参数:使用 PSSParameterSpec 设置 SHA-256 作为消息摘要算法,MGF1 作为掩码生成函数,盐长度为 32 字节,trailer field 为 1。
  3. 初始化签名:创建 Signature 对象,指定使用 SHA-256 和 RSA 的 PSS 模式。设置 PSS 参数并初始化签名对象以进行签名。
  4. 签名数据:提供需要签名的数据给签名对象,然后生成数字签名。
  5. 验证签名:使用公钥初始化签名对象,提供相同的数据,并使用 verify() 方法检查签名是否有效。

这个示例展示了如何在 Java 中使用 RSA PSS 签名机制进行数据的签名和验证,确保了数据的安全传输和验证过程的完整性。

4.3 小结

公钥加密和私钥解密确保了信息的机密性和安全传输,而私钥签名和公钥验签则提供了信息的完整性和来源验证。这些技术的正确实现和使用是确保数字通信安全的关键。

五、注意事项和最佳实践

在实际应用中,公钥和私钥的管理至关重要。这些密钥通常需要被安全地存储和管理,以防止未授权访问或泄露。例如,可以使用Java的KeyStore来安全地存储这些密钥。此外,选择合适的加密和签名算法也是保证安全的关键。在上述示例中,我们使用了RSA算法进行加密和签名,以及SHA256withRSA进行消息摘要和签名验证。这些算法因其强大的安全性而被广泛使用,但根据具体的安全需求和标准,可能会选择其他算法。

加密和签名的输出通常是二进制数据,这在实际应用中可能需要特别处理。例如,如果需要将加密或签名的数据以文本形式展示或传输,通常会使用Base64编码来转换这些二进制数据为可读的字符串格式。

六、结语

公钥加密和私钥签名是非对称加密技术中两个最基本也是最关键的应用。它们共同构成了现代数字安全通信的基础,广泛应用于数据传输、电子商务、数字身份验证等多个领域。通过这两种方法,我们不仅能保护数据免受未授权访问,还能验证数据的来源和完整性,从而确保通信的安全性和可靠性。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-10-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 陆业聪 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Java技术专题:「入门到精通系列」深入探索常用的六种加密技术和实现
随着信息安全的日益重要,加密技术在软件开发领域中扮演着关键的角色。Java作为一门广泛应用的编程语言,提供了丰富的加密库和API,使得开发者可以轻松实现各种加密算法。本文将深入探索Java技术中常用到的六种加密技术,包括对称加密、非对称加密、哈希算法、消息摘要、数字签名和数字证书,并通过具体的实现代码帮助读者更好地理解和应用这些加密技术。
IT_陈寒
2024/01/08
3430
Java技术专题:「入门到精通系列」深入探索常用的六种加密技术和实现
基础篇:java.security框架之签名、加密、摘要及证书
和前端进行数据交互时或者和第三方商家对接时,需要对隐私数据进行加密。单向加密,对称加密,非对称加密,其对应的算法也各式各样。java提供了统一的框架来规范(java.security)安全加密这类API。下面将一一介绍
潜行前行
2021/02/05
1.8K0
如何使用Java进行加密和解密
在Java中,我们可以使用许多不同的加密和解密技术来保护数据。这些技术可以用于加密密码、保护敏感数据、网络通信等。下面将介绍Java中常用的加密和解密技术和实现方法。
用户1289394
2023/09/22
7760
如何使用Java进行加密和解密
加解密算法分析与应用场景
在日常开发中,无论是使用何种编程语言,我们都会遇到加解密的需求。例如,为了保护接口数据安全,我们需要对数据进行加密传输;在HTTPS协议中,通过非对称加密传输客户端私钥,然后双方使用该私钥进行对称加密通信;使用MD5算法进行文件一致性校验等。然而,面对众多的加解密方案,我们往往不清楚何时使用哪种方法。本文将为您梳理当前主流的加解密技术,并对算法进行科普性说明,但不涉及具体算法分析。根据日常应用场景,加解密技术大致可分为以下四类:
不惑
2024/05/13
5990
加解密算法分析与应用场景
Java中的加密与安全,你了解多少
  什么是数据安全?假如Bob要给Alice发送一封邮件,在发送邮件的过程中,黑客可能会窃取到邮件的内容,所以我们需要防窃听;黑客也有可能会篡改邮件的内容,所以Alice必须要有能有去识别邮件是否被篡改;最后,黑客也可能假冒Bob给Alice发送邮件,所以Alice还必须有能力识别出伪造的邮件。所以数据安全的几个要点就是:防窃听、防篡改和防伪造。 古代的加密方式:
程序员波特
2024/01/19
2620
Java中的加密与安全,你了解多少
快速了解常用的非对称加密算法,再也不用担心面试官的刨根问底
加密算法通常被分为两种:对称加密算法和非对称加密算法。其中,对称加密算法在加密和解密时使用的密钥相同;非对称加密算法在加密和解密时使用的密钥不同,分为公钥和私钥。此外,还有一类叫做消息摘要算法,是对数据进行摘要并且不可逆的算法。
万猫学社
2022/04/22
1.6K0
快速了解常用的非对称加密算法,再也不用担心面试官的刨根问底
每日一博 - 对称加密算法 vs 非对称加密算法
我们今天来梳理一下将分别介绍这两种加密算法的优缺点,并通过Java代码实现和测试结果来验证其效果。
小小工匠
2023/05/29
4920
加密与安全_探索签名算法
在非对称加密中,使用私钥加密、公钥解密确实是可行的,而且有着特定的应用场景,即数字签名。
小小工匠
2024/05/26
2100
【网络安全】网络防护之旅 - 点燃网络安全战场的数字签名烟火
网络安全是一门关注计算机系统和网络安全的专业学科。其首要任务是维护信息系统的核心价值,包括机密性、完整性和可用性,以对抗未经授权的访问、破坏、篡改或泄露的威胁。
SarPro
2024/02/20
2000
【网络安全】网络防护之旅 - 点燃网络安全战场的数字签名烟火
区块链基础:非对称算法
1.Hash算法 package cn.hadron.security; import java.security.MessageDigest; import java.util.UUID; import org.eclipse.jetty.util.security.Credential.MD5; /** * crypto['krɪptoʊ]秘密成员, * 一些语言的crypto模块的目的是为了提供通用的加密和哈希算法 * 加密工具类 */ public class CryptoUtil
程裕强
2022/05/06
3970
区块链基础:非对称算法
【深度知识】RSA加密、解密、签名、验签的原理及方法
RSA加密是一种非对称加密。可以在不直接传递密钥的情况下,完成解密。者能够确保信息的安全性,避免了直接传递密钥所造成的被破解的风险。是由一对密钥来进行加解密的过程,分别称之为公钥和私钥。如果用公钥进行加密,则只能通过对应的私钥去解密,如果用私钥进行加密,则只能通过对应的公钥去解密。两者之间有数字相关,该加密发酸的原理就是对一极大整数做因数分解的困难行来保证安全性。通常个人保存私钥,公钥是公开的(可能同时多人持有)
辉哥
2021/03/02
6.9K0
【深度知识】RSA加密、解密、签名、验签的原理及方法
Java加密与解密之非对称加密算法
非对称加密算法与对称加密算法的主要差别在于非对称加密算法用于加密和解密的密钥不相同,非对称加密算法密钥分为公钥和私钥,公钥加密只能用私钥解密,反之私钥加密只能用公钥解密。相比对称加密算法,非对称加密算法加/解密效率低,但安全性高,这两种算法一般结合使用。常见非对称加密算法有RSA、ECC、Elgamal等。
布禾
2020/11/24
1.2K0
非对称加密之RSA是怎么加密的
前几天阿粉刚刚说了这个 MD5 加密的前世今生,因为 MD5 也确实用的人不是很多了,阿粉就不再继续的一一赘述了,今天阿粉想给大家分享的,是非对称加密中的一种,那就是 RSA 加密算法。
Java极客技术
2022/12/04
1.3K0
RSA非对称加密
需要注意的一点,这个公钥和私钥必须是一对的,如果用公钥对数据进行加密,那么只有使用对应的私钥才能解密,所以只要私钥不泄露,那么我们的数据就是安全的。
会跳舞的机器人
2018/09/03
1.6K0
[Java 安全]消息摘要与数字签名
该文介绍了如何使用Java实现数字签名,包括DSA、RSA和ECDSA算法。文章还介绍了Java中的KeyPair和Signature类,以及如何使用这些类来实现数字签名和验证。
静默虚空
2018/01/05
1.2K0
[Java 安全]消息摘要与数字签名
加密-解密详解
参考视频: https://www.bilibili.com/video/BV1tz4y197hm
用户5927264
2020/07/30
2.9K0
Java安全之安全加密算法
本篇文来谈谈关于常见的一些加密算法,其实在此之前,对算法的了解并不是太多。了解的层次只是基于加密算法的一些应用上。也来浅谈一下加密算法在安全领域中的作用。写本篇文也是基于算法的应用和实现,也是我的基本原则,能用就行。
全栈程序员站长
2021/04/07
1.4K0
Java安全之安全加密算法
Java使用RSA加密解密签名及校验
再来一个Base64的类,当然你也可以用commons-codec-1.9.jar
全栈程序员站长
2021/04/13
4.5K0
Java使用RSA加密解密签名及校验
RSA的java实现
RSA非对称加密整理 辅助类 package net.yun10000.zf.util; import Java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; public class RSAKeys { private RSAPublicKey publicKey; private RSAPrivateKey privateKey; public RSAPublicKey g
东营浪人
2019/09/05
7540
JAVA中的加密算法之双向加密(二)
本节主要讲述Java双向加密算法中的非对称加密算法实现。 (二)、非对称加密 1976年,美国学者Dime和Henman为解决信息公开传送和密钥管理问题,提出一种新的密钥交换协议,允许在不安全的媒体上的通讯双方交换信息,安全地达成一致的密钥,这就是“公开密钥系统”。相对于“对称加密算法”这种方法也叫做“非对称加密算法”。 与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥 (privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。 1. RSA 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。
幽鸿
2020/04/02
1.6K0
相关推荐
Java技术专题:「入门到精通系列」深入探索常用的六种加密技术和实现
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验