解决 WCF 错误:加密密钥子句未使用所需的加密令牌“System.IdentityModel.Tokens.X509S

本文关键字:加密 令牌 System Tokens IdentityModel X509S 错误 WCF 密钥 未使用 子句 | 更新日期: 2023-09-27 18:32:56

我有一个 WCF 客户端崩溃,并显示错误"EncryptedKey 子句未使用所需的加密令牌'System.IdentityModel.Tokens.X509SecurityToken'包装"。

我环顾四周,这篇博文似乎表明问题出在我的证书设置上,但我不确定我做错了什么......

为了安全起见,我的客户端使用带有互助证书绑定元素的自定义绑定,我正在代码中配置证书,如下所示:

client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.ChainTrust;
client.ClientCredentials.ServiceCertificate.SetDefaultCertificate
(
    StoreLocation.CurrentUser,
    StoreName.AddressBook,
    X509FindType.FindBySerialNumber,
    "[serial number 1]"
);
client.ClientCredentials.ClientCertificate.SetCertificate
(
    StoreLocation.CurrentUser,
    StoreName.My,
    X509FindType.FindBySerialNumber,
    "[serial number 2]"
);

序列号与请求和响应消息中<X509SerialNumber>元素中的值匹配。

我注意到的一个差异是请求中的<X509IssuerName>元素和响应的格式不同:

Request:  CN=[CN], O=[O], L=[L], C=[C]
Response: C=[C],L=[L],O=[O],CN=[CN]

这是否可能导致问题?

更新

事实证明,是证书名称格式导致了问题。我设法通过使用自定义编码器将响应中的证书名称替换为 WCF 期望的名称来解决此问题。现在我有这个丑陋的黑客,但它有效,所以我会忍受它!

public override Message ReadMessage(ArraySegment<byte> buffer, BufferManager bufferManager, string contentType)
{   
    var msgContents = new byte[buffer.Count];
    Array.Copy(buffer.Array, buffer.Offset, msgContents, 0, msgContents.Length);
    bufferManager.ReturnBuffer(buffer.Array);
    var message = Encoding.UTF8.GetString(msgContents);
    // Fix certificate issuer name formatting to match what WCF expects.
    message = message.Replace
    (
        "C=[C],L=[L],O=[O],CN=[CN]",
        "CN=[CN], O=[O], L=[L], C=[C]"
    );
    var stream = new MemoryStream(Encoding.UTF8.GetBytes(message));     
    return ReadMessage(stream, int.MaxValue);
}

解决 WCF 错误:加密密钥子句未使用所需的加密令牌“System.IdentityModel.Tokens.X509S

您提到的颁发者名称顺序很可能是问题所在。由于这些名称不是有符号的,因此我建议您在客户端中编写一个自定义编码器,以替换响应中要格式化为请求中的名称。

除了明显的证书不匹配和除非配置错误...我看到尝试访问私钥时出现问题。检查客户端是否对证书私钥具有适当的权限。如果在 certmanager 中右键单击证书,您应该会看到 AllTasks/Manage Private Keys。将客户端的进程标识添加到列表中。

还要确保您使用的证书正确无误。我使用了缺少主题密钥标识符的自签名证书。

WCF:EncryptedKey 子句未包装所需的加密令牌"System.IdentityModel.Tokens.X509SecurityToken">