在Azure中创建RSA-SHA 256加密字符串的BASE64编码版本函数C#

oogrdqng  于 2023-03-24  发布在  C#
关注(0)|答案(1)|浏览(145)

我正在Microsoft Azure中创建一个授权流,目前使用的是Logic应用程序(消费),还在Azure函数中编写了一些代码。
为了使流程正常工作,我需要创建一个“摘要”标题。下面粘贴了该标题的函数代码。这与预期的一样工作,并且正确创建了标题。
“摘要”创建:

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using System.Text;

namespace NordeaAuthorization
{
    public static class CreateDigest
    {
        [FunctionName("CreateDigest")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            string value = req.Query["value"];

            var crypt = new System.Security.Cryptography.SHA256Managed();
            var hash = new StringBuilder();
            byte[] crypto = crypt.ComputeHash(Encoding.UTF8.GetBytes(value));
            foreach (byte theByte in crypto)
            {
                hash.Append(theByte.ToString("x2"));
            }

            var response = Convert.ToBase64String(crypto);

            return new OkObjectResult(response);
        }
    }
}

我还需要提供一个“签名”头。这是我完全卡住了。
“Signature”头应该像这样创建:

  • 所有POST或PUT请求所需的签名标头为:“(request-target)x-bank-originating-host x-bank-originating-date content-type digest”:

POST:https://open.bank.com/corporate/v2/authorize X-Bank-Originating-Host:open.bank.comX-Bank-Originating-Date:Thu,05 Jun 2019 21:31:40 GMT content-type:application/json摘要:Signature:keyId="",algorithm=“rsa-sha256”,headers="(request-target)x-bank-originating-host x-bank-originating-date content-type digest”,signature=”
地点 *

  • <client_id>是分配给TPP的客户端应用程序的客户端Id是请求主体的散列(SHA 256)摘要是RSA-SHA 256加密签名字符串的BASE64编码版本

客户端将签名字符串组成为:
HTTP(请求目标):post /corporate/v2/authorize\n x-bank-originating-host:open.bank.com\n x-bank-originating-date:2019年6月5日星期四21:31:40 GMT\n内容类型:application/json\n摘要:SHA-256=jcC/ttW 7 JucGTN 9 hWfqMsFeON 6D +vZtQGWJA+ W 0 PL/g=(在上一个函数中创建)
请注意,上面包含的'\n'符号是为了演示应在何处插入新行字符。签名字符串的最后一行上没有新行。还请注意,上面显示的摘要值仅作为示例,实际上需要根据请求消息正文计算。*
如何在C#中的Azure函数中实现这一点?在哪里上传证书以及如何在尝试创建签名头时访问它?
我已经尝试将证书上传到Azure Key Vault,但它似乎无效,我已经就此联系了颁发者。它也是.p12文件,Azure Key Vault不支持。不确定证书是否存在实际问题,或者当我将文件扩展名更改为. pfx时发生了错误。仍然在等待颁发者的答复。
代码方面-还没有尝试任何东西,因为我不知道如何构建流本身。

z0qdvdin

z0qdvdin1#

若要创建“签名”标头,您需要在Azure函数中执行以下步骤。
使用HTTP方法、请求目标、标头和摘要值构造签名字符串。使用证书的私钥使用RSA-SHA 256加密对签名字符串进行签名。对生成的签名进行Base64编码。使用密钥ID、算法、标头和签名构造“Signature”标头。
若要在Azure Function C#中创建RSA-SHA 256加密字符串的BASE64编码版本,您需要执行以下步骤:
1.创建签名字符串:
签名字符串应包含以下内容:
HTTP(请求目标):post /corporate/v2/authorize\n x-bank-originating-host:open.bank.com\n x-bank-originating-date:Thu,21 Mar 2023 21:31:40 GMT\n content-type:application/json\n摘要:沙-

示例代码

public static class CreateSignature
    {
        private static readonly string KeyId = "your_key_id_here";
        private static readonly string Algorithm = "rsa-sha256";
        private static readonly string[] Headers = new string[] { "(request-target)", "x-bank-originating-host", "x-bank-originating-date", "content-type", "digest" };
        private static readonly string CertificateThumbprint = "your_certificate_thumbprint_here";

        [FunctionName("CreateSignature")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "post", "put", Route = null)] HttpRequest req,
            ILogger log)
        {
            log.LogInformation("C# HTTP trigger function processed a request.");

            var headers = new Dictionary<string, string>();
            foreach (var header in req.Headers)
            {
                headers.Add(header.Key.ToLower(), header.Value.ToString());
            }

            var method = req.Method.ToLower();
            var path = req.Path.Value.ToLower();

            var signingString = new StringBuilder();
            signingString.Append($"{method} {path}\n");
            foreach (var header in Headers)
            {
                if (header.Equals("(request-target)"))
                {
                    signingString.Append($"(request-target): {method} {path}\n");
                }
                else if (headers.ContainsKey(header))
                {
                    signingString.Append($"{header}: {headers[header]}\n");
                }
            }

            var digest = headers["digest"].Substring(7); // Remove the "SHA-256=" prefix
            var digestBytes = Convert.FromBase64String(digest);

            using (var store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
            {
                store.Open(OpenFlags.ReadOnly);
                var certificates = store.Certificates.Find(X509FindType.FindByThumbprint, CertificateThumbprint, false);
                var certificate = certificates[0];
                var privateKey = certificate.GetRSAPrivateKey();
                var signatureBytes = privateKey.SignData(Encoding.UTF8.GetBytes(signingString.ToString()), HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
                var signature = Convert.ToBase64String(signatureBytes);
                store.Close();

                // Construct the "Signature" header
                var signatureHeader = new StringBuilder();
                signatureHeader.Append($"keyId=\"{KeyId}\", ");
                signatureHeader.Append($"algorithm=\"{Algorithm}\", ");
                signatureHeader.Append($"headers=\"{string.Join(" ", Headers)}\", ");
                signatureHeader.Append($"signature=\"{signature}\"");

                return new OkObjectResult(signatureHeader.ToString());
            }
        }
    }

有关详细信息,请参阅MSDoc1MSDoc2

相关问题