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

投票系统中如何从RSA签名消息中获取原始消息内容?

问题分析与解决方案

你的核心问题在于混淆了RSA签名的作用:RSA签名是对原始消息的哈希值进行私钥加密生成的校验值,本身不包含原始消息内容,因此只传递签名的话,接收方根本无法获取到需要验证和解密的加密选票数据。

你需要把加密后的选票消息和对应的RSA签名一起传递给VotingSystem,才能完成签名验证和消息解密。以下是具体的修改方案:


1. 创建打包数据结构

首先定义一个类,用来同时携带加密后的选票和签名:

// 封装加密选票与签名的实体类
public class BallotPackage {
    private String encryptedBallot;
    private byte[] signature;

    public BallotPackage(String encryptedBallot, byte[] signature) {
        this.encryptedBallot = encryptedBallot;
        this.signature = signature;
    }

    // Getter方法
    public String getEncryptedBallot() { return encryptedBallot; }
    public byte[] getSignature() { return signature; }
}

2. 修改Voter类的vote方法

不再只传递签名,而是传递打包后的完整对象:

public void vote(String ballot, String gammaKey) throws Exception {
    String encryptedBallot = encrypt(ballot, gammaKey);
    byte[] signedMessage = signMessage(encryptedBallot);
    // 打包加密选票与签名后传递
    votingSystem.addBallot(new BallotPackage(encryptedBallot, signedMessage));
}

3. 修改VotingSystem类的相关方法

更新addBallot参数类型,完善签名验证与消息解密逻辑:

public class VotingSystem {
    // 替换原有byte列表为BallotPackage列表
    private ArrayList<BallotPackage> ballots = new ArrayList<>();

    // 更新addBallot方法
    public void addBallot(BallotPackage ballotPackage) {
        ballots.add(ballotPackage);
    }

    // 签名验证:使用打包对象中的加密选票数据进行校验
    private boolean verifySign(BallotPackage ballotPackage, PublicKey publicKey) throws Exception {
        Signature publicSignature = Signature.getInstance("SHA256withRSA");
        publicSignature.initVerify(publicKey);
        // 用加密后的选票消息更新签名验证器
        publicSignature.update(ballotPackage.getEncryptedBallot().getBytes(StandardCharsets.UTF_8));
        // 验证签名有效性
        return publicSignature.verify(ballotPackage.getSignature());
    }

    // 添加解密方法:还原原始选票内容
    private String decrypt(String encryptedBallot, String gammaKey) {
        gammaKey = fitGammaToMessage(encryptedBallot.length(), gammaKey);
        StringBuilder decryptedMessage = new StringBuilder();
        for (int i = 0; i < encryptedBallot.length(); i++) {
            // XOR解密逻辑与加密对称
            char C = (char) (encryptedBallot.charAt(i) ^ gammaKey.charAt(i));
            decryptedMessage.append(C);
        }
        return decryptedMessage.toString();
    }

    // 补充fitGammaToMessage方法(与Voter类实现一致,或抽取为公共工具方法)
    private String fitGammaToMessage(int length, String gammaKey) {
        StringBuilder sb = new StringBuilder(gammaKey);
        while (sb.length() < length) {
            sb.append(gammaKey);
        }
        return sb.substring(0, length);
    }

    // 示例:批量处理选票的方法
    public void processBallots(PublicKey voterPublicKey, String gammaKey) throws Exception {
        for (BallotPackage pkg : ballots) {
            // 先验证签名
            boolean isSignValid = verifySign(pkg, voterPublicKey);
            if (!isSignValid) {
                System.out.println("签名无效,丢弃选票");
                continue;
            }
            // 签名有效则解密选票
            String originalBallot = decrypt(pkg.getEncryptedBallot(), gammaKey);
            System.out.println("验证通过,原始选票内容:" + originalBallot);
            // 后续业务逻辑处理...
        }
    }
}

额外优化建议

  1. 避免不可打印字符问题:你的XOR加密可能生成不可打印ASCII字符,直接用String存储易导致数据损坏,建议将加密后的字节数组转成Base64字符串,解密时再转回字节数组。
  2. 密钥安全管理:伽马密钥(gammaKey)需安全传递给VotingSystem,禁止硬编码;RSA公钥的传递也要确保可信渠道。
  3. 完善异常处理:代码中需补充异常捕获逻辑,避免RuntimeException扩散。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 08:56:18