如何在javascript中对嵌套对象中的键顺序进行排序?

如何在javascript中对嵌套对象中的键顺序进行排序?,javascript,express,digital-signature,Javascript,Express,Digital Signature,问题是: 我有一个参数请求,如: { "foo": "bar", "bar": "baz", "baz" : { "nestedKey": "foo" } } 我需要用Hmac512算法对它进行签名,所以我需要首先对对象进行字符串化 但是,我担心的是,如果不保留密钥的顺序,服务器和客户端生成的签名可能会不同 要处理这个问题,我的想法只是对对象的键进行排序(包括嵌套在该对象中的键) 我怎样才能做到这一点 您需要确保消息的两面都相同,但根本不需要修改或调整消息 基本上应用这个算法 base64(

问题是: 我有一个参数请求,如:

{ "foo": "bar", "bar": "baz", "baz" : { "nestedKey": "foo" } }
我需要用Hmac512算法对它进行签名,所以我需要首先对对象进行字符串化

但是,我担心的是,如果不保留密钥的顺序,服务器和客户端生成的签名可能会不同

要处理这个问题,我的想法只是对对象的键进行排序(包括嵌套在该对象中的键)


我怎样才能做到这一点

您需要确保消息的两面都相同,但根本不需要修改或调整消息

基本上应用这个算法

 base64(sign(utf8(json message)))
客户端

  • Stringify:将javascript对象转换为字符串

  • UTF-8:确保您使用的是已知的和固定的编码,如UTF

  • 符号:计算结果消息上的HMAC

  • base64:将二进制签名转换为base64

  • 向客户端发送json消息和签名

    服务器端


    从客户端获取原始消息并应用步骤2-4。检查签名是否相等

    您需要确保消息的两面相同,但根本不需要修改或调整消息

    基本上应用这个算法

     base64(sign(utf8(json message)))
    
    客户端

  • Stringify:将javascript对象转换为字符串

  • UTF-8:确保您使用的是已知的和固定的编码,如UTF

  • 符号:计算结果消息上的HMAC

  • base64:将二进制签名转换为base64

  • 向客户端发送json消息和签名

    服务器端


    从客户端获取原始消息并应用步骤2-4。检查签名是否相等

    ,如OP中所述,HMAC过程的输入必须是确定性的

    但Javascript对象元素的顺序无法设置,无论我们多么希望它们是可设置的。(我经常看到这个问题再次出现。)

    答案是对字符串本身进行排序

    请参阅以获得解决方案


    然后将结果字符串输入HMAC方法。无需对其进行base64编码。

    如OP中所述,HMAC进程的输入必须是确定性的

    但Javascript对象元素的顺序无法设置,无论我们多么希望它们是可设置的。(我经常看到这个问题再次出现。)

    答案是对字符串本身进行排序

    请参阅以获得解决方案


    然后将结果字符串输入HMAC方法。无需对其进行base64编码。

    一个选项的可能重复项是-您可以使用object.keys获取密钥,然后对密钥进行排序并重新创建对象。如果我是您,我可能会按照@Nikhillital所说的做。如果您有嵌套对象,则必须递归地执行该操作,直到找到底部。。。相当不错。不管怎样,这个问题很有趣;)为什么订单对签名很重要?你不发送签名文本,但在另一端独立创建吗?我不确定是否可以使用bodyParser.json()中间件在expressjs中获取原始字符串而不是解析后的对象。其中一个选项可能重复-你可以使用Object.keys获取键,然后对键进行排序并重新创建对象。如果我是你,我可能会按照@Nikhillmittal说的去做。如果您有嵌套对象,则必须递归地执行该操作,直到找到底部。。。相当不错。不管怎样,这个问题很有趣;)为什么订单对签名很重要?你不发送签名文本,但在另一端独立创建它吗?我不确定是否可以使用bodyParser.json()中间件在expressjs中获取原始字符串而不是解析的对象。步骤3的作用是什么?难道你不想在HMAC的二进制结果上这样做吗?啊,不知怎么的,我把步骤混在一起了。谢谢@Bergi-1,因为stringify操作不是确定性的。Javascript对象元素的顺序无法设置,无论我们多么希望它们。请参阅我的答案以了解替代方案stringify@LarryK如果在服务器上对客户端发送的原始数据应用HMAC,则stringify元素的顺序是不相关的。与重新创建javascript对象和重新应用整个签名算法相比,它更简单,更不容易出错。也许我的答案并没有完全响应OP像你这样的要求,但它更简单,并且实现了相同的最终目标(如果我理解正确,那就是验证请求的完整性和真实性)。无论如何,谢谢你的评论!
    base64
    步骤3有什么好处?难道你不想在HMAC的二进制结果上这样做吗?啊,不知怎么的,我把步骤混在一起了。谢谢@Bergi-1,因为stringify操作不是确定性的。Javascript对象元素的顺序无法设置,无论我们多么希望它们。请参阅我的答案以了解替代方案stringify@LarryK如果在服务器上对客户端发送的原始数据应用HMAC,则stringify元素的顺序是不相关的。与重新创建javascript对象和重新应用整个签名算法相比,它更简单,更不容易出错。也许我的答案并没有完全响应OP像你这样的要求,但它更简单,并且实现了相同的最终目标(如果我理解正确,那就是验证请求的完整性和真实性)。无论如何,谢谢你的评论!