最近在调试某运营商短信接口API,接口会对使用UrlEncode的字符串进行签名验证,而在接口调用过程中,偶发性出现签名验证失败的问题。

经过反复测试,发现主要出现在存在一些特殊英文字符的情况下,比如英文的括号、英文的感叹号等,最后反查到 dotnet 中对 UrlEncode 有多种方法,并且返回的结果是有差异的。

dotnet 中主要的 UrlEncode 的方法,分别是:

WebUtility.UrlEncode

HttpUtility.UrlEncode

Uri.EscapeUriString

Uri.EscapeDataString

经过使用下面的代码测试

using System.Net;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(WebUtility.UrlEncode("(Hello, World!)"));

            Console.WriteLine(HttpUtility.UrlEncode("(Hello, World!)"));

            Console.WriteLine(Uri.EscapeUriString("(Hello, World!)"));

            Console.WriteLine(Uri.EscapeDataString("(Hello, World!)"));
            
        }
    }
}

输出结果为:

(Hello%2C+World!)
(Hello%2C+World!)
(Hello,%20World!)
%28Hello%2C%20World%21%29

从上面的输出结果可以看出:

1、WebUtility.UrlEncode、HttpUtility.UrlEncode、Uri.EscapeDataString 的编码并不会对英文的符号等特殊字符进行编码,而Uri.EscapeDataString则会对所有非英文字母的字符进行编码。

2、WebUtility.UrlEncode 和 HttpUtility.UrlEncode 会将空格转换成加号,而 Uri.EscapeUriString 和 Uri.EscapeDataString 会将空格转换成%20。

所以在遇到需要对编码后的字符串进行校验的情况下,需要测试下对方接口对特殊字符是否会进行转换。

PS:感觉这个对方提供的接口的验签逻辑也是有点怪,先对urlencode的字符串进行urldecode,然后再用它自己的urlencode逻辑进行编码后再验证签名,这就导致了urlencode调用端逻辑不一致,就会导致签名验证失败。


原文链接地址:http://blog.exsvc.cn/article/dotnet-urlencode-difference.html
转载请注明:转载自 易科博客 ,谢谢!

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注