Java RSA 密钥生成与签名验证实战

1. RSA 算法原理
  • 密钥生成

    1. 选择两个大素数 $p$ 和 $q$
    2. 计算模数 $n = p \times q$
    3. 计算欧拉函数 $\phi(n) = (p-1)(q-1)$
    4. 选择公钥指数 $e$ 满足 $1 < e < \phi(n)$ 且 $\gcd(e, \phi(n)) = 1$
    5. 计算私钥指数 $d$ 满足 $d \times e \equiv 1 \pmod{\phi(n)}$
  • 签名验证

    • 签名:$S = M^d \mod n$($M$ 为消息摘要)
    • 验证:$M' = S^e \mod n$,对比 $M'$ 与原始摘要

2. Java 实现代码
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

public class RSAExample {
    // 生成密钥对
    public static KeyPair generateKeyPair() throws Exception {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        keyGen.initialize(2048); // 密钥长度
        return keyGen.generateKeyPair();
    }

    // 签名
    public static String sign(String data, PrivateKey privateKey) throws Exception {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initSign(privateKey);
        signature.update(data.getBytes());
        return Base64.getEncoder().encodeToString(signature.sign());
    }

    // 验证
    public static boolean verify(String data, String signatureStr, PublicKey publicKey) throws Exception {
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(publicKey);
        signature.update(data.getBytes());
        return signature.verify(Base64.getDecoder().decode(signatureStr));
    }

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

        // 2. 签名示例
        String message = "重要交易数据";
        String signature = sign(message, privateKey);
        System.out.println("签名结果: " + signature);

        // 3. 验证签名
        boolean isValid = verify(message, signature, publicKey);
        System.out.println("验证结果: " + (isValid ? "通过" : "失败"));
    }
}


3. 关键组件解析
组件 作用 核心类
KeyPairGenerator 生成RSA密钥对 java.security.KeyPairGenerator
Signature 签名/验证操作 java.security.Signature
PKCS8EncodedKeySpec 私钥编码规范 java.security.spec.PKCS8EncodedKeySpec
X509EncodedKeySpec 公钥编码规范 java.security.spec.X509EncodedKeySpec
Base64 密钥/签名编解码 java.util.Base64

4. 执行流程
  1. 密钥生成

    graph LR
    A[初始化密钥生成器] --> B[设置密钥长度2048]
    B --> C[生成密钥对]
    C --> D[分离公钥/私钥]
    

  2. 签名过程

    graph LR
    E[原始数据] --> F[SHA-256哈希]
    F --> G[RSA私钥加密]
    G --> H[Base64编码]
    

  3. 验证过程

    graph LR
    I[接收签名] --> J[Base64解码]
    J --> K[RSA公钥解密]
    K --> L[对比原始哈希]
    


5. 注意事项
  1. 密钥长度:推荐使用 2048 位以上密钥
  2. 哈希算法:必须与签名时一致(如 SHA256)
  3. 密钥存储
    // 保存公钥
    String publicKeyStr = Base64.getEncoder().encodeToString(publicKey.getEncoded());
    
    // 还原公钥
    byte[] pubBytes = Base64.getDecoder().decode(publicKeyStr);
    KeyFactory keyFactory = KeyFactory.getInstance("RSA");
    PublicKey restoredPubKey = keyFactory.generatePublic(new X509EncodedKeySpec(pubBytes));
    

  4. 异常处理:需处理 NoSuchAlgorithmExceptionInvalidKeyException 等异常

通过此实现可完成数字签名、文档认证等安全场景,实际部署时建议使用硬件安全模块(HSM)保护私钥。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐