惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Forbes - Security
Forbes - Security
H
Hackread – Cybersecurity News, Data Breaches, AI and More
N
Netflix TechBlog - Medium
Engineering at Meta
Engineering at Meta
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
F
Fortinet All Blogs
P
Privacy & Cybersecurity Law Blog
The Hacker News
The Hacker News
博客园 - 司徒正美
博客园 - 聂微东
T
The Blog of Author Tim Ferriss
I
Intezer
WordPress大学
WordPress大学
Security Archives - TechRepublic
Security Archives - TechRepublic
Scott Helme
Scott Helme
T
Threat Research - Cisco Blogs
T
Tailwind CSS Blog
月光博客
月光博客
Recent Announcements
Recent Announcements
博客园 - 叶小钗
J
Java Code Geeks
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
C
Cyber Attacks, Cyber Crime and Cyber Security
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
N
News and Events Feed by Topic
A
Arctic Wolf
B
Blog RSS Feed
Recorded Future
Recorded Future
D
DataBreaches.Net
有赞技术团队
有赞技术团队
Project Zero
Project Zero
U
Unit 42
T
Tor Project blog
The GitHub Blog
The GitHub Blog
Hacker News - Newest:
Hacker News - Newest: "LLM"
C
CERT Recently Published Vulnerability Notes
博客园 - Franky
博客园 - 【当耐特】
Microsoft Security Blog
Microsoft Security Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Security Latest
Security Latest
C
Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Blog — PlanetScale
Blog — PlanetScale
H
Heimdal Security Blog
Vercel News
Vercel News
Stack Overflow Blog
Stack Overflow Blog
S
Securelist

博客园 - 江城2211

大数值的精度与格式化显示问题 【知识总结】数据库的事务、并发与锁管理 基于数据源连接,动态构造JPA上下文EntityManager 【转载】使用了HTTPS为啥还要接口数据加密? 国密SM2算法,加密、签名示例 【知识总结】JVM线程堆栈中的基础概念解读 【问题记录】JVM进程崩溃(hs_err_pid.log致命错误日志) [问题记录】存在视图依赖的数据表,DDL修改字段比如做扩容等注意事项 【编码技巧】批量校验或处理关联引用数据的优化总结 【问题总结】Garmin路线无法同步和地图坐标偏移的解决办法 【工具推荐】磁盘IO检测工具之Diskspd 【编码技巧】总结一个稳定而高效的方法,将二维关系数据转换为树形结构 【编程技巧】SQL脚本快速生成随机测试数据 【编程技巧】结合JPA通用分页与排序技术,支持百万级以上数据的DML批量处理方案 【使用技巧】CodeDecom.exe批量反编译JAR包+Beyond Compare对比 【问题记录】Cause: java.sql.SQLRecoverableException: No more data to read from socket JDBC与各数据库产品连接的驱动及URL示例 【问题记录】使用PowerDesigner连接数据库并反向工程生成所有表及关系 使用tcpdump抓取网络包,在wareshark查看对应请求及响应的原始报文
RSA加密算法,加解密、签名示例
江城2211 · 2025-09-10 · via 博客园 - 江城2211

Posted on 2025-09-10 20:50  江城2211  阅读(54)  评论()    收藏  举报

RSA加密算法,加解密、签名验签示例Demo:

package com.example.demo;
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RSAExample {
    private static final String ALGORITHM = "RSA";
    private static final int KEY_SIZE = 2048;
    private static final String TRANSFORMATION = "RSA/ECB/PKCS1Padding";
    // 签名算法(SHA256withRSA是常用的安全组合)
    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";

    // 生成密钥对
    public static KeyPair generateKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator generator = KeyPairGenerator.getInstance(ALGORITHM);
        generator.initialize(KEY_SIZE);
        return generator.generateKeyPair();
    }

    // 私钥加密
    // 私钥加密、公钥解密  从算法上来说是可以的,但与非对称加解密设计相违背
    // 在 RSA 中,使用私钥加密在数学上是可行的,但这违背了非对称加密的设计原则和安全最佳实践。
    public static String encryptByPrivateKey(PrivateKey privateKey, String data) throws Exception {
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, privateKey); // 用私钥初始化加密模式
        byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encrypted);
    }

    // 公钥解密
    public static String decryptByPublicKey(PublicKey publicKey, String encryptedData) throws Exception {
        byte[] data = Base64.getDecoder().decode(encryptedData);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, publicKey); // 用公钥初始化解密模式
        byte[] decrypted = cipher.doFinal(data);
        return new String(decrypted, StandardCharsets.UTF_8);
    }


    /**
     * 使用公钥加密数据
     * @param publicKey 公钥对象
     * @param data 待加密的明文
     * @return Base64编码的密文
     * @throws Exception 加密过程中可能出现的异常
     */
    public static String encrypt(PublicKey publicKey, String data) throws Exception {
        // 获取加密实例
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);

        // 初始化加密模式
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);

        // 执行加密并转为Base64
        byte[] encryptedBytes = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encryptedBytes);
    }

    /**
     * 使用私钥解密数据
     * @param privateKey 私钥对象
     * @param encryptedData Base64编码的密文
     * @return 解密后的明文
     * @throws Exception 解密过程中可能出现的异常
     */
    public static String decrypt(PrivateKey privateKey, String encryptedData) throws Exception {
        // 获取解密实例
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);

        // 初始化解密模式
        cipher.init(Cipher.DECRYPT_MODE, privateKey);

        // 执行解密
        byte[] encryptedBytes = Base64.getDecoder().decode(encryptedData);
        byte[] decryptedBytes = cipher.doFinal(encryptedBytes);
        return new String(decryptedBytes, StandardCharsets.UTF_8);
    }

    /**
     * 使用私钥对数据进行签名
     * @param privateKey 私钥对象
     * @param data 待签名的数据
     * @return Base64编码的签名结果
     * @throws Exception 签名过程中可能出现的异常
     */
    public static String sign(PrivateKey privateKey, String data) throws Exception {
        // 获取签名实例
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

        // 用私钥初始化签名器
        signature.initSign(privateKey);

        // 更新待签名的数据
        signature.update(data.getBytes(StandardCharsets.UTF_8));

        // 生成签名并转为Base64
        byte[] signBytes = signature.sign();
        return Base64.getEncoder().encodeToString(signBytes);
    }

    /**
     * 使用公钥验证签名
     * @param publicKey 公钥对象
     * @param data 原始数据
     * @param sign 待验证的签名(Base64编码)
     * @return 验证结果:true-验证通过,false-验证失败
     * @throws Exception 验签过程中可能出现的异常
     */
    public static boolean verify(PublicKey publicKey, String data, String sign) throws Exception {
        // 获取签名实例
        Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

        // 用公钥初始化验签器
        signature.initVerify(publicKey);

        // 更新原始数据
        signature.update(data.getBytes(StandardCharsets.UTF_8));

        // 验证签名
        byte[] signBytes = Base64.getDecoder().decode(sign);
        return signature.verify(signBytes);
    }

    // 私钥加密、公钥解密  从算法上来说是可以的,但与非对称加解密设计相违背
    // 在 RSA 中,使用私钥加密在数学上是可行的,但这违背了非对称加密的设计原则和安全最佳实践。
    public static String encryptByKey(Key key, String data) throws Exception{
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.ENCRYPT_MODE, key); // 初始化加密模式
        byte[] encrypted = cipher.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return Base64.getEncoder().encodeToString(encrypted);
    }
    public static String decryptByKey(Key key, String encryptedData) throws Exception {
        byte[] data = Base64.getDecoder().decode(encryptedData);
        Cipher cipher = Cipher.getInstance(TRANSFORMATION);
        cipher.init(Cipher.DECRYPT_MODE, key); // 用公钥初始化解密模式
        byte[] decrypted = cipher.doFinal(data);
        return new String(decrypted, StandardCharsets.UTF_8);
    }
    // 密钥格式转换工具方法
    public static PublicKey getPublicKey(byte[] bytes) throws Exception {
        X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);
        return KeyFactory.getInstance(ALGORITHM).generatePublic(spec);
    }

    public static PrivateKey getPrivateKey(byte[] bytes) throws Exception {
        PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);
        return KeyFactory.getInstance(ALGORITHM).generatePrivate(spec);
    }

    public static void main(String[] args) {
        try {
            // 1. 生成密钥对
            KeyPair keyPair = generateKeyPair();
            PrivateKey privateKey = keyPair.getPrivate();
            PublicKey publicKey = keyPair.getPublic();

            System.out.println("私钥: " + Base64.getEncoder().encodeToString(privateKey.getEncoded()));
            System.out.println("公钥: " + Base64.getEncoder().encodeToString(publicKey.getEncoded()));

            System.out.println();

            // 2. 原始数据
            String original = "======1111用私钥加密的数据";
            System.out.println("原始数据: " + original);

            // 3. 私钥加密
            String encrypted = encryptByPrivateKey(privateKey, original);
            System.out.println("私钥加密: " + encrypted);

            // 4. 公钥解密
            String decrypted = decryptByPublicKey(publicKey, encrypted);
            System.out.println("公钥解密: " + decrypted);


            System.out.println();
            //
            String original2 = "======2222用PublicKey加密的数据";
            System.out.println("原始数据:" +original2);
            // 5. 公钥加密
            String encrypted2 = encryptByKey(publicKey, original2);
            System.out.println("公钥加密: " + encrypted2);
            System.out.println("tkk: " + encryptByKey(publicKey, original2));

            // 6. 私钥解密
            String decrypted2 = decryptByKey(privateKey, encrypted2);
            System.out.println("私钥解密: " + decrypted2);


            String encrypted3 = encrypt(publicKey, original2);
            System.out.println("公钥加密:" + encrypted3);

            String decrypted3 = decrypt(privateKey, encrypted3);
            System.out.println("私钥解密:" + decrypted3);
            System.out.println("tkk:" + decrypt(privateKey, encrypted2));

            // 12. 待签名的数据
            String originalData = "这是需要RSA签名的数据,用于验证数据完整性和发送者身份";
            System.out.println("\n原始数据: " + originalData);

            // 13. 使用私钥签名
            String signature = sign(privateKey, originalData);
            System.out.println("签名结果(Base64): " + signature);

            // 14. 模拟传输后,使用公钥验签(正常情况)
            boolean verifySuccess = verify(publicKey, originalData, signature);
            System.out.println("正常数据验签结果: " + (verifySuccess ? "通过" : "失败"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

参考文章:https://cloud.tencent.com/developer/article/2499894