如何解决为Amazon Kinesis Signaling Channel C#创建一个预签名URL
我正在尝试使用C#websockets连接到Amazon Kinesis信令渠道。
为此,我需要一个预签名的url,但是无论我怎样尝试,我都会收到403禁止响应。
我知道我的凭据是正确的,因为我已经使用测试页进行了检查。 (https://awslabs.github.io/amazon-kinesis-video-streams-webrtc-sdk-js/examples/index.html)
我什至设法获取了页面生成的签名URL并成功连接到它。 但是,我自己对URL进行签名的所有尝试都失败了。
谁能告诉我我做错了什么? 这是我所拥有的:
using System;
using System.Security.Cryptography;
using System.Text;
using Amazon.Runtime;
using Amazon.SecurityToken.Model;
using Amazon.Util;
namespace AwsIotMqttWebSocketSigner
{
public static class sigv4Utils
{
private static readonly Encoding m_encoding = Encoding.UTF8;
private static StringBuilder AppendHex(this StringBuilder sb,byte[] bytes)
{
for (int i = 0; i < bytes.Length; i++)
{
sb.AppendFormat(bytes[i].ToString("x2"));
}
return sb;
}
private static StringBuilder AppendSha256Hex(this StringBuilder sb,string data)
{
byte[] bytes = m_encoding.GetBytes(data);
using (SHA256 algo = SHA256.Create())
{
byte[] hash = algo.ComputeHash(bytes);
sb.AppendHex(hash);
}
return sb;
}
private static byte[] GetHmac(string key,string data)
{
byte[] keyBytes = m_encoding.GetBytes(key);
return GetHmac(keyBytes,data);
}
private static byte[] GetHmac(byte[] key,string data)
{
using (HMACSHA256 kha = new HMACSHA256(key))
{
byte[] dataBytes = m_encoding.GetBytes(data);
byte[] hash = kha.ComputeHash(dataBytes);
return hash;
}
}
private static byte[] GetSignatureKey(string key,string date,string region,string service)
{
byte[] kDate = GetHmac("AWS4" + key,date);
byte[] kRegion = GetHmac(kDate,region);
byte[] kService = GetHmac(kRegion,service);
byte[] kCredentials = GetHmac(kService,"aws4_request");
return kCredentials;
}
static string CanonicalResourcePath(Uri endpointUri)
{
if (string.IsNullOrEmpty(endpointUri.AbsolutePath))
return "/";
// encode the path per RFC3986
return AWSSDKUtils.UrlEncode(endpointUri.AbsolutePath,true);
}
public const string EMPTY_BODY_SHA256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
internal static string GetSignedUri(
Uri uri,Credentials credentials,string channelARN
)
{
DateTime utcNow = CorrectClockSkew.GetCorrectedUtcNowForEndpoint(region);
string datetime = utcNow.ToString("yyyyMMddTHHmmssZ");
string date = datetime.Substring(0,8);
const string service = "kinesisvideo";
const string method = "GET";
const string algorithm = "AWS4-HMAC-SHA256";
string protocol = uri.Scheme;
string host = uri.Host;
string credentialScope = date + "/" + region + "/" + service + "/" + "aws4_request";
var canonicalQuerystring = new StringBuilder(800)
.Append("X-Amz-Algorithm=")
.Append(algorithm)
.Append("&X-Amz-ChannelARN=")
.Append(AWSSDKUtils.UrlEncode(channelARN,false))
.Append("&X-Amz-Credential=")
.Append(AWSSDKUtils.UrlEncode(credentials.AccessKeyId,false))
.Append("%2F")
.Append(AWSSDKUtils.UrlEncode(credentialScope,false))
.Append("&X-Amz-Date=")
.Append(datetime)
.Append("&X-Amz-Expires=299");
if (string.IsNullOrEmpty(credentials.SessionToken) == false)
{
canonicalQuerystring.Append("&X-Amz-Security-Token=")
.Append(AWSSDKUtils.UrlEncode(credentials.SessionToken,false));
}
canonicalQuerystring.Append("&X-Amz-SignedHeaders=host;x-amz-date");
var canonicalRequest = new StringBuilder(350)
.Append(method)
.Append('\n')
.Append(CanonicalResourcePath(uri))
.Append('\n')
.Append(canonicalQuerystring)
.Append("\n")
.Append("\nhost:")
.Append(host)
.Append("\nx-amz-date:")
.Append(datetime)
.Append("\n\nhost;x-amz-date\n")
.Append(EMPTY_BODY_SHA256)//.AppendSha256Hex(String.Empty)
.ToString();
var canonicalRequestStr = canonicalRequest.ToString();
var stringToSign = new StringBuilder(200)
.Append(algorithm)
.Append('\n')
.Append(datetime)
.Append('\n')
.Append(credentialScope)
.Append('\n')
.AppendSha256Hex(canonicalRequestStr)
.ToString();
byte[] signingKey = GetSignatureKey(credentials.SecretAccessKey,date,region,service);
byte[] signatureBytes = GetHmac(signingKey,stringToSign);
canonicalQuerystring
.Append("&X-Amz-Signature=")
.AppendHex(signatureBytes);
string requestUrl = protocol + "://" + host + uri.AbsolutePath + "?" + canonicalQuerystring;
return requestUrl;
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。