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

Java SecureRandom与GWT编译器兼容性问题求助

问题分析与解决方案

问题本质

你的核心问题是GWT 2.5.1的客户端JRE模拟库不包含java.security.SecureRandom:

  • Eclipse能编译通过是因为它只做普通Java代码编译,不做GWT的客户端转译;
  • GWT插件编译失败是因为它需要把客户端代码转译成JS,而所有用到的类必须在GWT的JRE模拟列表中,SecureRandom不在其中。

可行解决方案

方案1:将安全随机数生成逻辑移至服务端(推荐)

安全随机数的生成本就不应该放在客户端(客户端环境不可控,容易被篡改),完全符合Fortify的安全要求,同时避开GWT的限制:

  1. 定义GWT远程服务接口:
import com.google.gwt.user.client.rpc.RemoteService;
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;

@RemoteServiceRelativePath("secureRandomService")
public interface SecureRandomService extends RemoteService {
    // 示例:生成指定长度的随机字节数组
    byte[] generateSecureRandomBytes(int length);
    // 或者生成随机字符串等业务需要的格式
    String generateSecureRandomString(int length);
}
  1. 创建服务端实现类:
import java.security.SecureRandom;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class SecureRandomServiceImpl extends RemoteServiceServlet implements SecureRandomService {
    private final SecureRandom secureRandom = new SecureRandom();

    @Override
    public byte[] generateSecureRandomBytes(int length) {
        byte[] bytes = new byte[length];
        secureRandom.nextBytes(bytes);
        return bytes;
    }

    @Override
    public String generateSecureRandomString(int length) {
        byte[] bytes = new byte[length];
        secureRandom.nextBytes(bytes);
        return Base64.getEncoder().encodeToString(bytes).substring(0, length);
    }
}
  1. 客户端调用服务获取随机数:
SecureRandomServiceAsync service = GWT.create(SecureRandomService.class);
service.generateSecureRandomBytes(16, new AsyncCallback<byte[]>() {
    @Override
    public void onSuccess(byte[] result) {
        // 处理获取到的安全随机数
    }

    @Override
    public void onFailure(Throwable caught) {
        // 处理异常
    }
});

方案2:客户端使用JSNI封装原生JS安全随机API

如果业务必须在客户端生成安全随机数,可以通过GWT的JSNI调用浏览器原生的crypto.getRandomValues()(支持现代浏览器),封装成Java类使用:

public class ClientSecureRandom {
    // JSNI方法调用浏览器原生安全随机API
    private native void getRandomValues(byte[] array) /*-{
        if ($wnd.crypto && $wnd.crypto.getRandomValues) {
            $wnd.crypto.getRandomValues(array);
        } else if ($wnd.msCrypto && $wnd.msCrypto.getRandomValues) {
            // 兼容IE11
            $wnd.msCrypto.getRandomValues(array);
        } else {
            throw new Error("No secure random available in this browser");
        }
    }-*/;

    public void nextBytes(byte[] bytes) {
        if (bytes == null || bytes.length == 0) {
            return;
        }
        getRandomValues(bytes);
    }

    // 可扩展生成随机字符串等方法
    public String generateRandomString(int length) {
        byte[] bytes = new byte[length];
        nextBytes(bytes);
        return com.google.gwt.user.client.Base64.encode(bytes).substring(0, length);
    }
}

然后客户端直接使用这个类替代SecureRandom即可,GWT编译时能正常转译JSNI代码。

注意事项

  • 方案1是最安全且符合规范的做法,优先选择;
  • 方案2依赖浏览器的crypto API,需要确认你的目标浏览器都支持(IE11及以上、现代浏览器都支持);
  • 不要尝试“跳过编译”这类方案,会导致客户端代码运行时出错,且不符合安全要求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 08:02:42