难道这个API签名的请求方法安全吗? [英] Is this API signed request methodology secure?
问题描述
我正在验证我的 JSON-RPC API
并使用通过 POST $ C发送的请求签署我目前的工作策略$ C>在
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:
-
PUBLIC_KEY
被用于查找在SECRET_KEY
在数据库中。 -
SECRET_KEY
用来创建请求的HMAC从有效载荷
对象。 - 在有效载荷发送的
签名
散列相比对象的服务器上创建的请求的哈希值。如果它们匹配,我们进入到验证的
时间戳
。 - 鉴于我们现在可以信任
时间戳的明文形式发送
,因为它被列入请求
对象的从客户端发送签名
散,在时间戳
进行评估,如果要求太旧认证被拒绝。否则,该请求被认证
PUBLIC_KEY
is used to lookup theSECRET_KEY
in the DB.SECRET_KEY
is used to create an HMAC of therequest
object from the payload.- The
signature
hash sent in the payload is compared to the hash of therequest
object created on the server. If they match, we move on to authenticating thetimestamp
. - Given that we can now trust the
timestamp
sent in the cleartextrequest
object since it was included in thesignature
hash sent from the client, thetimestamp
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屋!