java - 签署 JSON 对象

标签 java php json pki

我必须在不同平台和服务实现之间交换 JSON 对象,并通过数字签名验证其完整性。所以平台 A 会创建这样一个对象并创建数字签名。然后将所述签名包含到对象中并发送到平台 B。JSON 对象可以包含任意属性和数据。

例如在 PHP 中:

function signObject($jsonObjectToSign, $privateKey) {
    $jsonObjectToSign->signature = "";
    $msgToSign = json_encode($jsonObjectToSign);

    openssl_sign($msgToSign, $jsonObjectToSign->signature, $privateKey, OPENSSL_SLGO_SHA1);

    return $jsonObjectToSign;
}

问题是,例如在 Java 中,无法判断 JSON 对象的属性是否与您添加它们的顺序相同(通过 JSONObject.put())。所以,如果我做一个

$json = json_encode('{"a":1, "b":2}');

在 PHP 中,如上所述签署此对象,将其传输到基于 java 的服务器,解码 json 对象,然后尝试验证签名,我可能会得到对象属性的不同顺序。

所以我需要的是一种从 JSONObject 创建 String 的可靠方法,与使用的语言或平台无关。

上面的示例对象需要始终输出 {"a":1, "b":2} 而从不输出 {"b":2, "a":1}。不幸的是,这是常见的情况,例如在 Java 中。

是否有任何以安全方式签署 JSON 对象的“最佳实践”?

但让我用另一种方式来描述这个问题:

假设我想用 Java(或任何其他语言)执行此操作:

JSONObject j = new JSONObject();
j.put("a", 1);
j.put("b", 2);

现在,我需要一个序列化函数,它始终为该对象输出相同的字符串表示形式,无论该对象是如何创建的以及使用何种语言创建的。

最佳答案

JSON 对象的签名和加密在 JOSE 规范套件中指定,其中 JOSE 代表 Javascript 对象签名和加密,请参阅 http://jose.readthedocs.org/en/latest/ JOSE 使用通过 JSON 对象的 base64url 编码表示计算的分离签名。签名不是 JSON 对象本身的一部分,因此不需要重新排序来验证它。

关于java - 签署 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31790802/

相关文章:

java - 方法什么时候应该返回 CompletableFuture?

java - 为什么我的 IntelliJ 插件没有显示在 Android Studio 中

php - 点击时的jquery事件

javascript - 在 Webkit 中使用 JavaScript 解析本地 JSON 文件

java - 如何将 Drawable 传递给类?

java - 是否可以从 Web 浏览器访问 JAX-WS?

php - 防止在 Yii 中加载特定的 CSS 文件

javascript - 使用ajax执行php插入功能

mysql - JSON 文件说明

java - Failcz.msebera.android.httpclient.client.HttpResponseException : Bad Request error while making HTTP request for weather app