Java常用工具算法-3--加密算法2--非对称加密算法(RSA常用,ECC,DSA)

1、定义与核心原理

  • 定义:使用一对密钥(公钥与私钥)的加密算法,公钥公开,私钥保密。加密和解密使用不同密钥,且无法通过公钥推导出私钥。

  • 关键点:解决了对称加密的密钥分发问题,但计算开销相对较大。

  • 基本流程:

    (1)、密钥生成

    • 每个用户生成一对密钥:公钥(Public Key) 和 私钥(Private Key),二者数学关联但无法互相推导。
      (2)、加密与解密
    • 加密:发送方使用接收方的 公钥 对数据加密。
    • 解密:接收方使用自己的 私钥 对密文解密。
      (3)、数字签名
    • 签名:发送方用 私钥 对数据哈希值加密,生成签名。
    • 验证:接收方用发送方的 公钥 解密签名,验证数据完整性与来源。
  • 示例场景(A向B发送消息)

    (1)、密钥分发

    • A生成公钥A和私钥A,B生成公钥B和私钥B。
    • A和B交换各自的公钥(公钥可公开)。
      (2)、加密传输
    • A用B的公钥加密消息,发送给B。
    • B用私钥B解密消息。
      (3)、数字签名
    • A用私钥A签名消息,B用公钥A验证签名。

2、特点

  • 优点:
    • 安全性高:基于数学难题(如大数分解、椭圆曲线离散对数),破解难度极高。
    • 密钥管理安全:公钥可公开,无需安全通道传输,解决了对称加密中密钥分发的难题。。
    • 支持数字签名:私钥签名,公钥验证,确保身份和数据完整性。
  • 可扩展性:适合大规模用户场景(如互联网通信)。
  • 缺点:
  • 速度慢,消耗大:加密/解密速度远低于对称加密,不适合大量数据。
  • 密钥管理复杂:需管理公钥的信任链(如证书颁发机构 CA)。

3、常见算法

(1)、RSA算法(常用)

  • 数学基础:大整数分解难题(分解两个大素数的乘积困难)。
  • 密钥生成:
    1. 选择两个大素数 p 和 q,计算 n = p × q。
    2. 计算欧拉函数 φ(n) = (p-1)(q-1)。
    3. 选择公钥指数 e(与 φ(n) 互质,通常为65537)。
    4. 计算私钥指数 d,满足 e × d ≡ 1 mod φ(n)。
  • 加密/解密公式:
    • 加密:C = M^e mod n(M为明文)。
    • 解密:M = C^d mod n。
  • 特点:
    • 安全性:依赖大素数分解,密钥长度建议 2048位以上。
    • 速度:较慢,适合加密少量数据(如密钥交换或签名)。
  • 应用场景:
    • HTTPS/TLS证书、SSL、SSH、数字签名。

(2)、ECC(椭圆曲线加密)

  • 数学基础:椭圆曲线上的离散对数问题(在有限域上求解困难)。
  • 密钥生成:
    1. 选择椭圆曲线参数(如基点 G、素数 p)。
    2. 生成私钥 d(随机数)。
    3. 计算公钥 Q = d × G(椭圆曲线点乘运算)。
  • 加密/解密:
    • 使用椭圆曲线 Diffie-Hellman(ECDH)协议协商密钥,或直接加密(如ECIES)。
  • 特点:
    • 高效性:256位ECC ≈ 3072位RSA的安全性,密钥更短,计算更快。
    • 适合资源受限设备:IoT、移动设备。
  • 应用场景:
    • 区块链(比特币、以太坊)、TLS 1.3、移动支付(Apple Pay)。

(3)、DSA(数字签名算法)

  • 数学基础:离散对数问题(基于素数域上的困难性)。
  • 密钥生成:
    1. 选择素数 p(主模数)、素数 q(q | p-1)、基点 g。
    2. 生成私钥 x(随机数),公钥 y = g^x mod p。
  • 签名生成:
    1. 选择随机数 k,计算 r = (g^k mod p) mod q。
    2. 计算 s = (k^{-1}(H(M) + x·r)) mod q。
  • 验证:
    1. 计算 w = s^{-1} mod q。
    2. 计算 u1 = H(M)·w mod q,u2 = r·w mod q。
    3. 验证 r ≡ (g{u1}·y{u2} mod p) mod q。
  • 特点:
    • 仅用于签名,不能直接加密数据。
    • 安全性:NIST标准,但密钥管理需谨慎(随机数 k 泄露会导致私钥泄露)。
  • 应用场景:
    • 政府标准(美国联邦系统)、SSL证书(部分CA)。

(4)、Diffie-Hellman(密钥交换协议)

  • 数学基础:离散对数问题。
  • 流程:
    1. 公开参数:素数 p 和基 g。
    2. A生成私钥 a,计算 A = g^a mod p 并发送给B。
    3. B生成私钥 b,计算 B = g^b mod p 并发送给A。
    4. A计算共享密钥:K = B^a mod p = g^{ab} mod p。
    5. B计算共享密钥:K = A^b mod p = g^{ab} mod p。
  • 特点:
    • 仅用于密钥协商,不直接加密数据。
    • 需结合对称加密(如AES)实现通信加密。
  • 应用场景:
    • TLS/SSL握手阶段协商对称密钥。

分类对比:

选择建议:

  • RSA:兼容性好,但密钥长。
  • ECC:高效且短密钥,适合现代场景。
  • DSA:NIST标准,但仅用于签名。

4、应用场景

(1)、密钥交换

  • HTTPS/TLS:客户端与服务器通过非对称加密协商对称密钥(如ECDH),后续通信使用AES加密。(即:明文数据通过协商的AES加密,AES秘钥在使用服务端公钥也加密;服务端先用私钥解密得到AES秘钥,在用AES秘钥解密获取明文数据)
  • SSH:建立安全的远程连接。(如:Git 代码仓库的 SSH 认证)

(2)、数字签名

  • 软件签名:Windows、Android应用签名(SHA256withRSA)。
  • 区块链:比特币交易签名(ECDSA)、以太坊账户签名(Ethereum使用ECDSA或Ed25519)。

(3)、身份认证

  • SSL证书:服务器用私钥解密客户端数据,验证身份。
  • SSH登录:通过公钥认证用户身份。

(4)、安全协议

  • PGP/PGP:邮件加密与签名。
  • IPSec:网络层安全通信。- 典型应用:

5、代码示例

(1)、RSA示例

c 复制代码
import java.security.*;
import java.util.Base64;

public class RSAExample {

    public static void main(String[] args) throws Exception {
        String originalText = "Confidential Message";
        System.out.println("Original Text: " + originalText);

        // 生成RSA密钥对
        KeyPair keyPair = generateRSAKeyPair();
        PublicKey publicKey = keyPair.getPublic();    // 公钥
        PrivateKey privateKey = keyPair.getPrivate();    // 私钥

        // 加密
        String encryptedText = encrypt(originalText, publicKey);
        System.out.println("Encrypted Text: " + encryptedText);

        // 解密
        String decryptedText = decrypt(encryptedText, privateKey);
        System.out.println("Decrypted Text: " + decryptedText);
    }
    
	// 生成密钥对
    private static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");   // RSA算法
        keyGen.initialize(2048); // 2048位
        return keyGen.generateKeyPair();
    }

    // 公钥加密
    private static String encrypt(String plainText, PublicKey publicKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");   // RSA,ECB模式,SHA-256哈希,填充
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] encryptedBytes = cipher.doFinal(plainText.getBytes());     // 密文
        return Base64.getEncoder().encodeToString(encryptedBytes);       // 密文是字节数组,转base64得到字符串
    }
	
	// 私钥解密
    private static String decrypt(String encryptedText, PrivateKey privateKey) throws Exception {
        Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privateKey);
        byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText));     // 反base64得到加密字节数组,在解密得到原文的字节数组
        return new String(decryptedBytes);    // 在获取原始明文字符串
    }
}

解释:

  • 密钥对生成:使用KeyPairGenerator生成RSA密钥对。
  • 加密模式:使用OAEP填充方式,基于SHA-256和MGF1(Mask Generation Function 1)。
  • 应用场景:适合加密小量数据(如对称密钥),不适合直接加密大量数据。

(2)、数字签名示例:(RSA+SHA-256)

c 复制代码
import java.security.*;
import java.util.Base64;

public class DigitalSignatureExample {

    public static void main(String[] args) throws Exception {
        String message = "This is a secure message";

        // 生成RSA密钥对
        KeyPair keyPair = generateRSAKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();

        // 签名
        String signature = signMessage(message, privateKey);
        System.out.println("Digital Signature: " + signature);

        // 验证签名
        boolean isVerified = verifySignature(message, signature, publicKey);
        System.out.println("Signature Verified: " + isVerified);
    }
	
	// 生成秘钥对
    private static KeyPair generateRSAKeyPair() throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048);
        return keyGen.generateKeyPair();
    }
	
	// 私钥生成签名
    private static String signMessage(String message, PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(message.getBytes());
        byte[] digitalSignature = signature.sign();      // 生成签名,得到签名字节数组
        return Base64.getEncoder().encodeToString(digitalSignature);      // base64得到签名字符串
    }

	// 公钥验证签名
    private static boolean verifySignature(String message, String signature, PublicKey publicKey) throws Exception {
        Signature sig = Signature.getInstance("SHA256withRSA");
        sig.initVerify(publicKey);
        sig.update(message.getBytes());            // 原始数据结合公钥处理,用于验证签名
        return sig.verify(Base64.getDecoder().decode(signature));   // 验证签名
    }
}

解释:

  • 签名生成:使用私钥对消息的SHA-256哈希值进行加密。
  • 签名验证:使用公钥验证签名是否有效。

6、对称和非对称加密对比和混合使用

(1)、对比

(2)、混合

1、优势

结合对称加密和非对称加密的优势,解决两者的不足:

  • 对称加密处理大量数据的高效性。
  • 非对称加密解决密钥分发的安全性。

2、混合使用流程

  1. 生成临时对称密钥:发送方随机生成一个临时对称密钥(如 AES 密钥)。
  2. 加密数据:使用临时对称密钥加密明文,生成密文。
  3. 加密密钥:使用接收方的公钥加密临时对称密钥。
  4. 传输数据:将加密后的密文和加密后的对称密钥发送给接收方。
  5. 解密密钥:接收方使用私钥解密临时对称密钥。
  6. 解密数据:使用临时对称密钥解密密文,还原明文。
    解释:
    对称加密更快,体积更小用于加密完整的数据;在使用非对称加密,加密临时的对称秘钥,这样就既安全,也更快捷。后端通过私钥解密得到临时对称秘钥,在用临时秘钥去还原原始数据。

3、典型应用

  • HTTPS:TLS 协议使用 RSA/ECDH 加密临时 AES 密钥。
  • 电子邮件加密(如 PGP):结合 RSA 和 AES 实现安全通信。

逆风翻盘,Dare To Be!!!

相关推荐
算AI21 分钟前
人工智能+牙科:临床应用中的几个问题
人工智能·算法
我不会编程5551 小时前
Python Cookbook-5.1 对字典排序
开发语言·数据结构·python
李少兄1 小时前
Unirest:优雅的Java HTTP客户端库
java·开发语言·http
此木|西贝1 小时前
【设计模式】原型模式
java·设计模式·原型模式
可乐加.糖1 小时前
一篇关于Netty相关的梳理总结
java·后端·网络协议·netty·信息与通信
无名之逆1 小时前
Rust 开发提效神器:lombok-macros 宏库
服务器·开发语言·前端·数据库·后端·python·rust
s9123601011 小时前
rust 同时处理多个异步任务
java·数据库·rust
9号达人1 小时前
java9新特性详解与实践
java·后端·面试
cg50171 小时前
Spring Boot 的配置文件
java·linux·spring boot
似水এ᭄往昔1 小时前
【C语言】文件操作
c语言·开发语言