难道这个API签名的请求方法安全吗? [英] Is this API signed request methodology secure?

查看:180
本文介绍了难道这个API签名的请求方法安全吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在验证我的 JSON-RPC API 并使用通过 POST SSL

I'm working on authentication for my JSON-RPC API and my current working strategy is using signed requests sent via POST over SSL.

我想知道如果任何人都可以看到,我还没有与下面的签名方法考虑的任何漏洞。

I'm wondering if anyone can see any vulnerabilities that I haven't taken into consideration with the following signature method.

在客户端和服务器之间的所有通信是通过 POST发送过来 SSL 请求完成。不安全的 HTTP 请求由API服务器直接拒绝。

All communication between the client and the server is done via POST requests sent over SSL. Insecure http requests are denied outright by the API server.

依赖

var uuid = require('node-uuid');
var crypto = require('crypto');
var moment = require('moment');
var MyAPI = require('request-json').newClient('https://api.myappdomain.com');

依赖关系链接:节点UUID ,的加密时刻 请求JSON

瓦尔

var apiVersion = '1.0';
var publicKey = 'MY_PUBLIC_KEY_UUID';
var secretKey = 'MY_SECRET_KEY_UUID';

请求对象

var request = {
    requestID : uuid.v4(),
    apiVersion : apiVersion,
    nonce : uuid.v4(),
    timestamp : moment.utc( new Date() ),
    params : params
}

签名

var signature = crypto.createHmac('sha512',secretKey).update(JSON.stringify(request)).digest('hex');

载荷包装(通过 POST SSL 以明文格式发送)

Payload Packaging (Sent as cleartext via POST over SSL)

var payload = {
    request: request,
    publicKey : publicKey,
    signature : signature
}

合力载荷JSON文件

{
  "request" : {
    "requestID" : "687de6b4-bb02-4d2c-8d3a-adeacd2d183e",
    "apiVersion" : "1.0",
    "nonce" : "eb7e4171-9e23-408a-aa2b-cd437a78af22",
    "timestamp" : "2014-05-23T01:36:52.225Z",
    "params" : {
      "class" : "User"
      "method" : "getProfile",
      "data" : {
        "id" : "SOME_USER_ID"
      }
    }
  },
  "publicKey" : "PUBLIC_KEY",
  "signature" : "7e0a06b560220c24f8eefda1fda792e428abb0057998d5925cf77563a20ec7b645dacdf96da3fc57e1918950719a7da70a042b44eb27eabc889adef95ea994d1",
}

POST请求

MyAPI.post('/', payload, function(response){
    /// Handle any errors ...
    /// Do something with the result ...
    /// Inspect the request you sent ...
});

服务器端

,然后在服务器端将发生以下情况进行身份验证的要求:

And then on the server-side the following occurs to authenticate the request:


  1. PUBLIC_KEY 被用于查找在 SECRET_KEY 在数据库中。

  2. SECRET_KEY 用来创建请求的HMAC从有效载荷对象。

  3. 在有效载荷发送的签名散列相比对象的服务器上创建的请求的哈希值。如果它们匹配,我们进入到验证的时间戳

  4. 鉴于我们现在可以信任时间戳的明文形式发送 ,因为它被列入请求对象的从客户端发送签名散,在时间戳进行评估,如果要求太旧认证被拒绝。否则,该请求被认证

  1. PUBLIC_KEY is used to lookup the SECRET_KEY in the DB.
  2. SECRET_KEY is used to create an HMAC of the request object from the payload.
  3. The signature hash sent in the payload is compared to the hash of the request object created on the server. If they match, we move on to authenticating the timestamp.
  4. Given that we can now trust the timestamp sent in the cleartext request object since it was included in the signature hash sent from the client, the timestamp is evaluated and the authentication is rejected if the request is too old. Otherwise, the request is authenticated.

据我了解,这是送过来 SSL 签名和认证请求的安全方法。这是正确的?

So far as I understand, this is a secure method for signing and authentication requests sent over SSL. Is this correct?

感谢您事先的任何帮助。

Thanks in advance for any help.

这是JSON产权制度的更新

Update on JSON Property Order

使用时性能的顺序 JSON.stringify 基本上是随机的,这可能导致签名的错配。

The order of properties when using JSON.stringify is essentially random, which could cause signature mis-matches.

使用这个签名过程中,在过去的几个星期我都没有遇到任何的散列不匹配的问题,由于物业的JSON 要求对象的顺序。我相信这是因为我只在字符串化要求对象文本一次,计算客户端的哈希权利之前。然后,要求对象是JSON格式为负载的一部分。一旦由服务器接收,散列从JSON对象直接创建在有效负载中接收的,有调用没有第二 JSON.stringify 方法,所以签名总是因为顺序相匹配的特性被确定一次,由客户端。我会继续寻找到这虽然,因为它似乎是一个薄弱点,如果不存在安全问题。

Using this signing process over the past few weeks I haven't run into any hash mis-match issues due to the order of the properties in the JSON request object. I believe it's because I only stringify the request object literal once, right before the client-side hash is calculated. Then, the request object is in JSON format as part of the payload. Once received by the server, the hash is created directly from the JSON object received in the payload, there's no second JSON.stringify method invoked, so the signature always matches because the order of the properties is determined once, by the client. I'll keep looking into this though as it seems like a weak point, if not a security concern.

推荐答案

JSON.stringify 不保证性能的秩序。例如,对象

JSON.stringify does not guarantee order of properties. For example, object

{
  a: 1,
  b: 2
}

可以通过两种方式进行序列化: {一:1,B:2} {B:2, 一:1} 。他们是从视图JSON点相同,但它们会导致它不同的HMACs。

could be serialized in two ways: {"a":1,"b":2} or {"b":2,"a":1}. They are the same from JSON point of view but they will result it different HMACs.

成像,对于引援的 JSON.stringify 生产第一种形式,但对于检查签名第二个。虽然签名是有效的签名检查将失败。

Imaging, that for signings your JSON.stringify produced first form, but for checking signature second one. Your signature check will fail although signature was valid.

这篇关于难道这个API签名的请求方法安全吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆