转载

签名验证到底使用SortedMap、LinkedHashMap、HashMap中的哪一个

签名验证到底使用SortedMap、LinkedHashMap、HashMap中的哪一个
技术岛公众号

最近同事发现有接口签名验证通不过,查了许久,发现,两边的验签规则不一样。最大的差异在于时间戳是否参与参数的排序。使用较多的版本是时间戳参与参数排序,而突然出一个接口中的时间戳不参与排序,导致算出来的签名值不一样。让我们使用一段main方法来感受一下其中的差异。

签名验证到底使用SortedMap、LinkedHashMap、HashMap中的哪一个
代码堆得好不如财富增值好

public static void main(String[] args) {

System.out.println(“SortedMap”);

SortedMap<String, String> sortedDict = new TreeMap<>(Collator.getInstance());

sortedDict.put(“B”, “B”);

sortedDict.put(“A”, “A”);

sortedDict.put(“C”, “C”);

System.out.println(sortedDict);

System.out.println(“LinkedHashMap”);

Map<String, String> dic = new LinkedHashMap<>();

dic.put(“B”, “B”);

dic.put(“A”, “A”);

dic.put(“C”, “C”);

System.out.println(dic);

System.out.println(“HashMap”);

Map<String, String> hashMapDic = new HashMap<>();

hashMapDic.put(“B”, “B”);

hashMapDic.put(“A”, “A”);

hashMapDic.put(“C”, “C”);

System.out.println(hashMapDic);

}

输出的结果:

SortedMap

{A=A, B=B, C=C}

LinkedHashMap

{B=B, A=A, C=C}

HashMap

{A=A, B=B, C=C}

很显示,当我们使用SortedMap、HashMap来处理签名参数的时候,参数自动排序了,而当我们使用LinkedHashMap处理的时候参数则不会排序。

造成问题产生的原因,看起来是使用了LinkedHashMap导致的,仔细分析,完全是两种签名处理思路导致的。

推荐思路一:使用SortedMap、HashMap做预处理,与顺序无关

不推荐思路二,没有对url中的query参数做任何预处理,直接在尾部附加上了时间戳,省了一步参数预处理。

思路二的问题在于,参数的顺序会影响最终签名,调用方需要知晓参数顺序。如果大家都知道并严格执行签名顺序,思路二其实也是正常的可行的。但是一般来讲,团队成员可能不断变化,一不留神就掉进这个洞里了。推荐使用思路一进行签名验证。

思路一与思路二的验证方式如何对接上呢?

在思路一追加时间戳之前,需要创建一个LinkedHashMap,将处理过的参数put进去,再将时间戳put进去,之后生成的签名URL就与思路二是一致的。

小结:当我们设计接口签名规则时,可以遵循一下一个重要的规则,参数顺序无关。

签名参考流程:

1.参数提取,记得使用SortedMap或HashMap

2.过滤处理

3.生成待签名URL

4.签名

5.生成签名后的URL

签名验证到底使用SortedMap、LinkedHashMap、HashMap中的哪一个

签名验证到底使用SortedMap、LinkedHashMap、HashMap中的哪一个
技术岛公众号
原文  http://www.jishudao.com/2019/04/10/sortedmap_linkedhashmap_hashmap/
正文到此结束
Loading...