【问题标题】:How can I sign a JWT token on an Azure WebJob without getting a CryptographicException?如何在 Azure WebJob 上签署 JWT 令牌而不收到 CryptographicException?
【发布时间】:2017-04-11 15:16:45
【问题描述】:

我有一个需要创建 JWT 令牌以与外部服务通信的 WebJob。当我在本地计算机上运行 WebJob 时,以下代码有效:

public static string SignES256(byte[] p8Certificate, object header, object payload)
{
    var headerString = JsonConvert.SerializeObject(header);
    var payloadString = JsonConvert.SerializeObject(payload);

    CngKey key = CngKey.Import(p8Certificate, CngKeyBlobFormat.Pkcs8PrivateBlob);
    using (ECDsaCng dsa = new ECDsaCng(key))
    {
        dsa.HashAlgorithm = CngAlgorithm.Sha256;
        var unsignedJwtData = Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(headerString)) + "." + Base64UrlEncoder.Encode(Encoding.UTF8.GetBytes(payloadString));
        var signature = dsa.SignData(Encoding.UTF8.GetBytes(unsignedJwtData));
        return unsignedJwtData + "." + Base64UrlEncoder.Encode(signature);
    }
}

但是,当我将 WebJob 部署到 Azure 时,出现以下异常:

Microsoft.Azure.WebJobs.Host.FunctionInvocationException:执行函数时出现异常:NotificationFunctions.QueueOperation ---> System.Security.Cryptography.CryptographicException:系统找不到指定的文件。在 System.Security.Cryptography.NCryptNative.ImportKey(SafeNCryptProviderHandle provider, Byte[] keyBlob, String format) at System.Security.Cryptography.CngKey.Import(Byte[] keyBlob, CngKeyBlobFormat format, CngProvider provider)

它说找不到指定的文件,但是我传入的参数不是在查看文件位置,而是在内存中。根据我收集到的信息,我可能需要启用某种加密设置才能使用 CngKey.Import 方法,但我在 Azure 门户中找不到与此相关的任何设置。

我也尝试过使用 JwtSecurityTokenHandler,但它似乎无法处理我需要使用的 ES256 哈希算法(即使它在 JwtAlgorithms 类中被引用为 ECDSA_SHA256)。

任何建议将不胜感激!

更新

似乎 CngKey.Import 实际上可能试图将证书存储在 Azure 上无法访问的某个位置。我不需要存储它,所以如果有更好的方法来访问内存中的证书或将其转换为更容易使用的不同类型的证书。

更新 2

此问题可能与 Azure Web Apps IIS 设置未加载用户配置文件有关,如 here 所述。我通过在 Azure 门户应用程序设置中设置 WEBSITE_LOAD_USER_PROFILE = 1 来启用此功能。我在通过 Azure 中的 WebJob 和 Web 应用程序运行代码时尝试了此更新,但我仍然收到相同的错误。

【问题讨论】:

  • 如果您尝试在您的开发机器上本地运行它是否会显示相同的错误?
  • 不,在我的机器上本地运行它作为 WebJob 工作正常,没有抛出异常。
  • 您的证书是从哪里导入的?我的意思是在 Azure 上
  • 证书是一个 Pkcs8 文件,我目前在我的 web.config 中只是一个 base64 字符串(也许不是最好的地方)并将它加载到一个字节数组中。它是传递给方法的“p8Certificate”变量。

标签: azure azure-webjobs


【解决方案1】:

我使用反编译器来了解 CngKey.Import 方法实际上在做什么。看起来它试图将我正在使用的证书插入到“Microsoft 软件密钥存储提供程序”中。我实际上不需要这个,只需要读取证书的值,但看起来不可能。

一旦我意识到证书被插入到机器某处的商店中,我开始思考如果你的 Azure Web 应用程序像它一样在共享环境中运行,那么从安全的角度来看这将是多么糟糕对于免费和共享层。果然,我的虚拟机在共享层上。将其扩展到基本层解决了这个问题。

【讨论】:

    猜你喜欢
    • 2019-11-17
    • 2018-03-11
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    • 2020-05-14
    相关资源
    最近更新 更多