You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Java API执行RSA签名及基于BigInteger的验证技术问询

RSA Signing & Verification with Java API and BigInteger

Hey there! I see you're looking to implement RSA signing and verification using Java—both with the standard API and your custom BigInteger-based RSA class. Let's walk through both approaches step by step.

1. Standard Java API Implementation

Java's java.security package has all the tools you need for RSA signing without rolling your own BigInteger logic. Here's how to do it:

Generate RSA Key Pair

import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

public class StandardRSAExample {
    public static KeyPair generateRSAKeyPair(int keySize) throws NoSuchAlgorithmException {
        KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
        SecureRandom secureRandom = new SecureRandom();
        keyGen.initialize(keySize, secureRandom);
        return keyGen.generateKeyPair();
    }
}

Sign Data with Private Key

Signing requires hashing the data first (we'll use SHA-256 here) and then encrypting the hash with the private key:

import java.security.PrivateKey;
import java.security.Signature;
import java.util.Base64;

public static String signData(String data, PrivateKey privateKey) throws Exception {
    Signature signature = Signature.getInstance("SHA256withRSA");
    signature.initSign(privateKey);
    signature.update(data.getBytes());
    byte[] signedBytes = signature.sign();
    return Base64.getEncoder().encodeToString(signedBytes);
}

Verify Signature with Public Key

To verify, we hash the original data again, decrypt the signature with the public key, and compare the two hashes:

import java.security.PublicKey;

public static boolean verifySignature(String data, String signedData, PublicKey publicKey) throws Exception {
    Signature signature = Signature.getInstance("SHA256withRSA");
    signature.initVerify(publicKey);
    signature.update(data.getBytes());
    byte[] decodedSignature = Base64.getDecoder().decode(signedData);
    return signature.verify(decodedSignature);
}

2. Enhancing Your Custom BigInteger-Based RSA Class

Your existing code starts the key generation process, but let's complete it and add signing/verification methods. First, let's define a RSAKeyPair class to hold the public (n, e) and private (n, d) keys:

class RSAKeyPair {
    private BigInteger n; // Modulus
    private BigInteger e; // Public exponent
    private BigInteger d; // Private exponent

    public RSAKeyPair(BigInteger n, BigInteger e, BigInteger d) {
        this.n = n;
        this.e = e;
        this.d = d;
    }

    // Getters
    public BigInteger getN() { return n; }
    public BigInteger getE() { return e; }
    public BigInteger getD() { return d; }
}

Now complete the RSA class with full key generation, signing, and verification:

import java.security.SecureRandom;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

class RSA { 
    public static RSAKeyPair generateKeyPair(int size) { 
        SecureRandom rnd = new SecureRandom(); 
        BigInteger p = new BigInteger(size / 2, 100, rnd); 
        BigInteger q = new BigInteger(size / 2, 100, rnd); 
        BigInteger n = p.multiply(q); 
        BigInteger phi = p.subtract(BigInteger.ONE).multiply(q.subtract(BigInteger.ONE)); 
        BigInteger e; 
        // Find e: must be coprime with phi, 1 < e < phi
        do { 
            e = new BigInteger(phi.bitLength(), rnd); 
        } while (e.compareTo(BigInteger.ONE) <= 0 || e.compareTo(phi) >= 0 || !e.gcd(phi).equals(BigInteger.ONE));
        
        // Calculate private exponent d: modular inverse of e mod phi
        BigInteger d = e.modInverse(phi);
        return new RSAKeyPair(n, e, d);
    }

    // Sign data: hash first, then apply private key operation (m^d mod n)
    public static BigInteger sign(String data, RSAKeyPair keyPair) throws NoSuchAlgorithmException {
        // Hash the data with SHA-256
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] hash = md.digest(data.getBytes());
        BigInteger hashBigInt = new BigInteger(1, hash); // Positive big integer from hash bytes
        
        // Sign: hash^d mod n
        return hashBigInt.modPow(keyPair.getD(), keyPair.getN());
    }

    // Verify signature: decrypt signature with public key (s^e mod n) and compare to hash of original data
    public static boolean verify(String data, BigInteger signature, RSAKeyPair keyPair) throws NoSuchAlgorithmException {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] originalHash = md.digest(data.getBytes());
        BigInteger originalHashBigInt = new BigInteger(1, originalHash);
        
        // Decrypt signature: s^e mod n
        BigInteger decryptedSignature = signature.modPow(keyPair.getE(), keyPair.getN());
        
        // Compare the decrypted signature with the original hash
        return decryptedSignature.equals(originalHashBigInt);
    }
}

Quick Key Notes

  • Always hash data before signing: RSA is designed to sign small values (like hashes), not large raw data. Using SHA-256 ensures we're working with a fixed-size, secure input.
  • Key size: For modern security, use at least 2048-bit keys (3072-bit is better for long-term protection).
  • SecureRandom: Never skip using SecureRandom for key generation—it ensures your keys are unpredictable and hard to crack.

内容的提问来源于stack exchange,提问作者user9676331

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:26:33