/// <summary>
        /// 获取添加密钥签名后的查询字符串。
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="accessKeyId">AccessKeyId。</param>
        /// <param name="accessKeySecret">AccessKeySecret。</param>
        /// <param name="algorithmName">签名 HMAC 哈希算法名称。</param>
        /// <returns></returns>
        public static string GetKeyedSignedQueryString(Uri uri, string accessKeyId, string accessKeySecret, string algorithmName)
        {
            if (string.IsNullOrWhiteSpace(accessKeyId))
            {
                throw new ArgumentNullException(nameof(accessKeyId), "AccessKeyId is not nullable.");
            }
            if (string.IsNullOrWhiteSpace(accessKeySecret))
            {
                throw new ArgumentNullException(nameof(accessKeySecret), "AccessKeySecret is not nullable.");
            }

            IDictionary <string, string> sortedQueryStrings = GetSortedQueries(uri);
            string signRequiredQueryString = GetSignRequiredQueryString(sortedQueryStrings, accessKeyId);

            using (KeyedHashAlgorithm hashAlgorithm = CryptoConfig.CreateFromName(algorithmName) as KeyedHashAlgorithm)
            {
                if (hashAlgorithm == null)
                {
                    throw new NotSupportedException($"Algorithm \"{algorithmName}\" is not supported for query keyed signature.");
                }

                hashAlgorithm.Key = Encoding.UTF8.GetBytes(accessKeySecret);
                sortedQueryStrings[QUERY_NAME_SIGNATURE] = BitConverter.ToString(hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(signRequiredQueryString))).Replace("-", "").ToLower();
                return(string.Join("&", sortedQueryStrings.Select(q => $"{PercentEncodingUtil.Encode(q.Key)}={PercentEncodingUtil.Encode(q.Value)}")));
            }
        }
예제 #2
0
        public void ConvertTest()
        {
            const string STR_DECODED_EN = "C# is the best!";
            const string STR_ENCODED_EN = "C%23%20is%20the%20best%21";
            const string STR_DECODED_CH = "C# ����õ����ԣ�";
            const string STR_ENCODED_CH = "C%23%20%E6%98%AF%E6%9C%80%E5%A5%BD%E7%9A%84%E8%AF%AD%E8%A8%80%EF%BC%81";

            Assert.Equal(STR_ENCODED_EN, PercentEncodingUtil.Encode(STR_DECODED_EN));
            Assert.Equal(STR_DECODED_EN, PercentEncodingUtil.Decode(STR_ENCODED_EN));
            Assert.Equal(STR_ENCODED_CH, PercentEncodingUtil.Encode(STR_DECODED_CH));
            Assert.Equal(STR_DECODED_CH, PercentEncodingUtil.Decode(STR_ENCODED_CH));
        }
        /// <summary>
        /// 获取添加简单签名后的查询字符串。
        /// </summary>
        /// <param name="uri"></param>
        /// <param name="algorithmName">签名哈希算法名称。</param>
        /// <returns></returns>
        public static string GetSimpleSignedQueryString(Uri uri, string algorithmName)
        {
            IDictionary <string, string> sortedQueryStrings = GetSortedQueries(uri);
            string requiredSignatureQueryString             = GetSignRequiredQueryString(sortedQueryStrings);

            using (HashAlgorithm hashAlgorithm = CryptoConfig.CreateFromName(algorithmName) as HashAlgorithm)
            {
                if (hashAlgorithm == null)
                {
                    throw new NotSupportedException($"Algorithm \"{algorithmName}\" is not supported for query simple signature.");
                }

                sortedQueryStrings[QUERY_NAME_SIGNATURE] = BitConverter.ToString(hashAlgorithm.ComputeHash(Encoding.UTF8.GetBytes(requiredSignatureQueryString))).Replace("-", "").ToLower();
                return(string.Join("&", sortedQueryStrings.Select(q => $"{PercentEncodingUtil.Encode(q.Key)}={PercentEncodingUtil.Encode(q.Value)}")));
            }
        }
        private static string GetSignRequiredQueryString(IDictionary <string, string> sortedQueryStrings, string accessKeyId = null)
        {
            sortedQueryStrings[QUERY_NAME_NONCE] = Guid.NewGuid().ToString("N").ToLower();
            if (!string.IsNullOrEmpty(accessKeyId))
            {
                sortedQueryStrings[QUERY_NAME_ACCESSKEYID] = accessKeyId;
            }

            IEnumerable <string> signRequiredQueries = sortedQueryStrings
                                                       .Where(q =>
                                                              !QUERY_NAME_SIGNATURE.Equals(q.Key, StringComparison.InvariantCultureIgnoreCase) &&
                                                              !q.Key.StartsWith("_") &&
                                                              !string.IsNullOrWhiteSpace(q.Value)
                                                              ).Select(q =>
                                                                       $"{PercentEncodingUtil.Encode(q.Key)}={PercentEncodingUtil.Encode(q.Value)}"
                                                                       );

            return(string.Join("&", signRequiredQueries));
        }