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

Android固定种子生成相同随机数时Bouncy Castle随机生成器选型咨询

Android平台基于Bouncy Castle实现固定种子可复现随机数

Android原生SecureRandom从4.2版本开始,调用setSeed()时仅会将用户传入的种子追加到系统熵池,不会替换原有系统熵,因此无法输出确定的随机序列,这是平台预设的安全设计,无法通过配置修改。

重要提示:下文实现的确定性随机数生成器不具备密码学安全的不可预测性,仅适用于单元测试、可复现仿真、确定性内容生成等场景,禁止用于密钥生成、签名、加密等安全敏感场景。

生成器选型

直接选择Bouncy Castle的DigestRandomGenerator即可,这是BC库中最轻量、行为最可控的确定性生成器:

  • 初始化后不会主动读取任何系统熵,所有输出完全由内部状态和传入的种子决定
  • 相同种子、相同调用顺序下,跨Android版本、跨设备的输出完全一致
  • 实现逻辑简单,没有隐式的种子补充逻辑,不会出现类似SecureRandom的不可控行为
    如果有NIST SP 800-90A合规要求,可以使用SP800SecureRandomBuilder构建DRBG实例,构建时必须显式传入仅返回固定种子的自定义熵源,关闭默认的系统熵读取逻辑。

依赖配置

不要使用Android系统内置的裁剪版Bouncy Castle,不同厂商、不同系统版本的内置BC实现存在定制修改,会导致同种子输出不一致。请在gradle中引入官方发布的完整依赖:

dependencies {
    implementation 'org.bouncycastle:bcprov-jdk15on:1.70'
}

可直接复用的实现代码

import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.prng.DigestRandomGenerator;
import java.nio.charset.StandardCharsets;
import java.util.Random;

public class DeterministicRng extends Random {
    private final DigestRandomGenerator generator;

    public DeterministicRng(byte[] fixedSeed) {
        // 选用SHA-256作为摘要核心,跨版本一致性稳定
        generator = new DigestRandomGenerator(new SHA256Digest());
        // 仅使用传入的固定种子初始化,无额外熵注入
        generator.addSeedMaterial(fixedSeed);
    }

    @Override
    public void setSeed(long seed) {
        // 兼容long类型种子输入,行为和JDK标准Random一致
        if (generator != null) {
            generator.addSeedMaterial(seed);
        }
    }

    public void setSeed(byte[] seed) {
        generator.addSeedMaterial(seed);
    }

    @Override
    public void nextBytes(byte[] dst) {
        generator.nextBytes(dst);
    }

    @Override
    protected int next(int bitCount) {
        int byteLen = (bitCount + 7) / 8;
        byte[] buf = new byte[byteLen];
        generator.nextBytes(buf);
        int res = 0;
        for (int i = 0; i < byteLen; i++) {
            res = (res << 8) | (buf[i] & 0xFF);
        }
        return res >>> (byteLen * 8 - bitCount);
    }
}

验证方式

传入相同种子调用,所有环境下输出完全固定:

// 固定测试种子
byte[] seed = "my_fixed_seed_2024".getBytes(StandardCharsets.UTF_8);
DeterministicRng rng = new DeterministicRng(seed);
// 任意设备、任意Android版本上,连续调用的输出完全一致
System.out.println(rng.nextInt());
System.out.println(rng.nextLong());
System.out.println(rng.nextFloat());

避坑说明

  • 不要使用SecureRandom.getInstance("SHA1PRNG", "BC")获取实例,部分BC版本的SHA1PRNG服务提供者实现仍会默认读取系统熵补充种子,无法保证输出确定性
  • 不要混用不同版本的Bouncy Castle库,不同版本的摘要算法或生成器逻辑调整可能导致输出差异,生产环境请锁定依赖版本
  • 若必须使用确定性随机数做安全相关操作(极度不推荐),请额外对生成序列做合规校验,固定种子的随机数本质上不具备抗预测能力

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:48:09