Skip to content

Commit

Permalink
🎨 SmsSenderProvider
Browse files Browse the repository at this point in the history
  • Loading branch information
Lxy829 committed Nov 14, 2023
1 parent cd78737 commit c7771d3
Showing 1 changed file with 37 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,14 @@ public SmsSenderProvider(ILogger<SmsSenderProvider> logger, SmsOptions? options,

#endregion

#region 华为云短信签名 SDK
#region helpers

async Task<HttpRequestMessage> Sign(string appKey, string appSecret, string apiAddress, FormUrlEncodedContent bodyContent, CancellationToken cancellationToken)
static async Task<HttpRequestMessage> Sign(string appKey, string appSecret, string apiAddress, FormUrlEncodedContent bodyContent, CancellationToken cancellationToken)
{
HttpRequestMessage request = new(HttpMethod.Post, apiAddress);
request.Content = new StringContent(await bodyContent.ReadAsStringAsync(), Encoding.UTF8, "application/x-www-form-urlencoded");
HttpRequestMessage request = new(HttpMethod.Post, apiAddress)
{
Content = bodyContent,
};

var time = request.Headers.TryGetValues(HeaderXDate, out var xdate) ? xdate.FirstOrDefault() : null;
DateTime xdateTime;
Expand All @@ -54,8 +56,8 @@ async Task<HttpRequestMessage> Sign(string appKey, string appSecret, string apiA
}
request.Headers.TryAddWithoutValidation(HeaderHost, request.RequestUri!.Host);
var signedHeaders = SignedHeaders(request.Headers);
var canonicalRequest = await CanonicalRequest(request, signedHeaders, bodyContent, cancellationToken);
var stringToSign = await StringToSign(canonicalRequest, xdateTime);
using var canonicalRequest = await CanonicalRequest(request, signedHeaders, bodyContent, cancellationToken);
using var stringToSign = await StringToSign(canonicalRequest, xdateTime);
var signature = SignStringToSign(stringToSign, Encoding.UTF8.GetBytes(appSecret));
var authValue = AuthHeaderValue(signature, appKey, signedHeaders);
request.Headers.TryAddWithoutValidation(HeaderAuthorization, authValue);
Expand All @@ -77,7 +79,7 @@ static SortedList<string> SignedHeaders(HttpHeaders headers)
return a;
}

async Task<byte[]> CanonicalRequest(HttpRequestMessage req, IList<string> signedHeaders, FormUrlEncodedContent body, CancellationToken cancellationToken)
static async Task<MemoryStream> CanonicalRequest(HttpRequestMessage req, IList<string> signedHeaders, FormUrlEncodedContent body, CancellationToken cancellationToken)
{
var bodyString = await body.ReadAsStringAsync(cancellationToken);
var data = Encoding.UTF8.GetBytes(bodyString);
Expand Down Expand Up @@ -123,62 +125,55 @@ void CanonicalHeaders()
}
}

foreach (var item in signedHeaders)
for (int i = 0; i < signedHeaders.Count; i++)
{
memorySteam.Write(item);
if (item != signedHeaders[signedHeaders.Count - 1]) memorySteam.Write(";"u8);
memorySteam.Write(signedHeaders[i]);
if (i != signedHeaders.Count - 1)
memorySteam.Write(";"u8);
}

memorySteam.Write("\n"u8);
memorySteam.Write(hexencode);
return memorySteam.ToArray();
return memorySteam;
}

async Task<byte[]> StringToSign(byte[] canonicalRequest, DateTime time)
static async Task<MemoryStream> StringToSign(MemoryStream canonicalRequest, DateTime time)
{
using MemoryStream stream = new MemoryStream(canonicalRequest);
var bytes = await SHA256.HashDataAsync(stream);
using MemoryStream memorySteam = new();
canonicalRequest.Position = 0;
var bytes = await SHA256.HashDataAsync(canonicalRequest);
MemoryStream memorySteam = new();
memorySteam.Write(Algorithm);
memorySteam.Write("\n");
memorySteam.Write(time.ToUniversalTime().ToString(BasicDateFormat));
memorySteam.Write("\n");
memorySteam.Write(ToHexString(bytes));
return memorySteam.ToArray();
memorySteam.Write(bytes.ToHexString(true));
return memorySteam;
}

string SignStringToSign(byte[] stringToSign, byte[] signingKey)
static string SignStringToSign(MemoryStream stringToSign, byte[] signingKey)
{
stringToSign.Position = 0;
using var hmacsha256 = new HMACSHA256(signingKey);
var hm = hmacsha256.ComputeHash(stringToSign);
return ToHexString(hm);
}

static string ToHexString(byte[] value)
{
int num = value.Length * 2;
char[] array = new char[num];
int num2 = 0;
for (int i = 0; i < num; i += 2)
{
byte b = value[num2++];
array[i] = GetHexValue(b / 16);
array[i + 1] = GetHexValue(b % 16);
}
return new string(array, 0, num);
return hm.ToHexString(true);
}

static char GetHexValue(int i)
static string AuthHeaderValue(string signature, string appKey, IList<string> signedHeaders)
{
if (i < 10)
using MemoryStream memorySteam = new();
memorySteam.Write(Algorithm);
memorySteam.Write(" Access="u8);
memorySteam.Write(appKey);
memorySteam.Write(", SignedHeaders="u8);
for (int i = 0; i < signedHeaders.Count; i++)
{
return (char)(i + '0');
memorySteam.Write(signedHeaders[i]);
if (i != signedHeaders.Count - 1)
memorySteam.Write(";"u8);
}
return (char)(i - 10 + 'a');
}

string AuthHeaderValue(string signature, string appKey, IList<string> signedHeaders)
{
return string.Format("{0} Access={1}, SignedHeaders={2}, Signature={3}", Algorithm, appKey, string.Join(";", signedHeaders), signature);
memorySteam.Write(", Signature="u8);
memorySteam.Write(signature);
return Encoding.UTF8.GetString(memorySteam.ToArray());
}

#endregion
Expand Down

0 comments on commit c7771d3

Please sign in to comment.