如何在Java和JavaScript之间传递字节数组

8
我需要从Javascript访问SecureRandom Java对象。我最终的目标是从PRNG中获取4个字节并将其转换为Javascript整数变量。根据http://download.oracle.com/javase/1.4.2/docs/api/java/security/SecureRandom.html,以下两行Java代码应该抓取4个随机字节:
byte bytes[] = new byte[4];
random.nextBytes(bytes);

我的问题是我不知道如何: 1)分配适合传递给Java方法的字节数组 2)在之后将该数组解析为整数

到目前为止,我已经成功获取了getSeed()方法,它返回一组随机字节。当我在Firefox中呈现下面提供的HTML代码时,它显示“[B@16f70a4”,这似乎是一个指针或其他东西。

<script>
var sprng = new java.security.SecureRandom();
random = sprng.getSeed(4);
document.write(random + "<br/>\n");
</script>

这让我想到我成功地实例化和访问了Java类,但在类型转换方面遇到了问题。
请问有人能帮我编写< strong> allocateJavaByteArray(N) 和< strong> convertJavaByteArrayToInt(N) 以使以下代码正常工作吗?
var sprng = new java.security.SecureRandom();
var nextBytes = allocateJavaByteArray(4);
srng.nextBytes(nextBytes);
var nextInt = convertJavaByteArrayToInt(4);

Thank you in advance.


你处于什么奇怪的上下文中,可以从<script>标签中获取Java运行时?我认为这里可能存在一些混淆。 - Pointy
我已在Ubuntu上的Firefox 3.0中进行了测试。另请参见http://docstore.mik.ua/orelly/webprog/jscript/ch22_03.htm。 - abb
寻找一个好的Java JSON编码类,并将JSON作为任何数据传递给JavaScript。顺便说一句,我也不明白您如何将Java放入<script>标签中。 - naugtur
除非您更喜欢保持否认,否则请考虑检查我提供的链接和/或在基于Mozilla的浏览器中运行我在OP中提供的JavaScript代码。但它不适用于IE。 - abb
旧问题,我知道,但你有解决方案吗?我也遇到了同样的问题... - Altealice
最干净的解决方案似乎是创建 Java Applet,并从 JavaScript 调用其方法。其他方法不具有可移植性。我在需要为客户提供修复问题的建议时发布了原始问题。但是客户选择接受安全风险,因为他们不想使应用程序复杂化,所以我没有准备任何 PoC 代码。当您说您有相同的问题时,它就是完全相同的问题(您需要良好的 PRNG),还是您需要转换数组? - abb
4个回答

2
您可以这样实现convertJavaByteArrayToInt
function convertJavaByteArrayToInt(bytes) {
  var r = 0;
  for (var i = 0; i < bytes.length; i++) {
    r += (bytes[i] & 0xff) << (8 * i);
  }
  return r;
}

allocateJavaByteArray很难实现,因为我们无法获取byteClass。所以不能使用java.lang.reflect.Array.newInstance创建一个byte[]实例。但是这里有一个巧妙的实现方法:

function allocateJavaByteArray(n) {
  var r = "";
  for (var i = 0; i < n; i++) {
    r += "0";
  }
  return new java.lang.String(r).getBytes();
}

更新:似乎上面的代码在FireFox 3.6中不起作用。这里有另一种allocateJavaByteArray实现,请尝试:

function allocateJavaByteArray(n) {
  var r = new java.io.ByteArrayOutputStream(4);
  for (var i = 0; i < n; i++) {
    r.write(0);
  }
  return r.toByteArray();
}

谢谢。我已经尝试了你的代码:http://pastebin.com/UW59urTW。不幸的是,convertJavaByteArrayToInt()返回0。我不知道这是一个转换问题还是SPRNG调用不正确。 - abb
convertJavaByteArrayToInt(4) 更改为 **convertJavaByteArrayToInt(nextBytes)**,你就能得到想要的结果。 - baotuo
一样的结果,我还是得到了0。我在Ubuntu上使用Firefox 3.6.17尝试过了。你用什么浏览器/平台测试成功了吗? - abb
数组分配似乎存在问题。如果我尝试获取其长度,我得到的是“public netscape.javascript.JSException(int,java.lang.Object)”,而不是预期的4。有什么线索吗?这是更新后的代码:http://pastebin.com/fFr9rwqz - abb
我在FF4.01/MacOSX上进行了测试,一切正常。 - baotuo
我已经更新了答案并在FireFox3.6/MacOSX中通过了测试。你可以试试看。 - baotuo

0
你可以先生成一个随机整数,像这样:
var nextInt = sprng.nextInt();

什么是 TypeScript 中 byte 的服务类型?https://dev59.com/Mcz6oIgBc1ULPQZFz16j - mattsmith5

0

Java字符串是唯一可以在Java->JS或JS->Java之间传递而不会头疼的东西。

byte[]或任何数组在JS中将被视为JSObject。


var sprng = new java.security.SecureRandom();

var foo= new java.package.SomeClass();

能在 Netscape/Mozilla/FF 中工作

它需要访问类,因此任何Java标准类或者您需要加载一个JAR然后访问该类。


对于原始问题:

  1. 创建带有实用方法的小程序:

    public String someStringEncodedValue(){ return 1+"|"+2; }

  2. 将小程序包含到具有唯一ID的页面中

  3. 使用唯一ID查找小程序的JS

  4. 调用方法

  5. 解析字符串(按|拆分)


0
通常情况下,您会在服务器上生成随机数字,并将其通过请求传递到jsp页面。

Tony,感谢您的评论,但JSP与我的情况无关。一切都发生在客户端。 - abb
@abb 也许你把Java和JavaScript混淆了? - rapadura

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接