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

推荐订阅源

S
Schneier on Security
GbyAI
GbyAI
H
Help Net Security
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
T
The Blog of Author Tim Ferriss
Vercel News
Vercel News
Microsoft Azure Blog
Microsoft Azure Blog
Google DeepMind News
Google DeepMind News
Stack Overflow Blog
Stack Overflow Blog
AWS News Blog
AWS News Blog
Spread Privacy
Spread Privacy
Apple Machine Learning Research
Apple Machine Learning Research
L
LINUX DO - 最新话题
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
P
Privacy International News Feed
C
CERT Recently Published Vulnerability Notes
C
Cybersecurity and Infrastructure Security Agency CISA
I
Intezer
Hugging Face - Blog
Hugging Face - Blog
H
Heimdal Security Blog
N
News and Events Feed by Topic
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Troy Hunt's Blog
大猫的无限游戏
大猫的无限游戏
SecWiki News
SecWiki News
Martin Fowler
Martin Fowler
人人都是产品经理
人人都是产品经理
Recent Commits to openclaw:main
Recent Commits to openclaw:main
Application and Cybersecurity Blog
Application and Cybersecurity Blog
F
Fortinet All Blogs
Hacker News: Ask HN
Hacker News: Ask HN
Know Your Adversary
Know Your Adversary
Hacker News - Newest:
Hacker News - Newest: "LLM"
博客园 - 聂微东
S
Secure Thoughts
云风的 BLOG
云风的 BLOG
O
OpenAI News
The Cloudflare Blog
Jina AI
Jina AI
U
Unit 42
L
Lohrmann on Cybersecurity
Attack and Defense Labs
Attack and Defense Labs
The Register - Security
The Register - Security
G
Google Developers Blog
量子位
Simon Willison's Weblog
Simon Willison's Weblog
V
Visual Studio Blog
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
G
GRAHAM CLULEY
TaoSecurity Blog
TaoSecurity Blog

博客园 - 江城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