C# WCF 肥皂符号 Sha256“密钥集不存在”
本文关键字:密钥 不存在 Sha256 WCF 肥皂 符号 | 更新日期: 2023-09-27 18:34:24
我调用一个需要WSS的Web服务。时间戳和正文块应由数字签名签名(我使用 USB 令牌(
我通过使用AsymmetricSecurityBindingElement
来完成这项工作。
如果使用DefaultAlgorithmSuite
,则签名请求消息可以完美运行。但是当DefaultAsymmetricSignatureAlgorithm
被CustomDefaultAlgorithmSuite
类更改为RsaSha256Signature
时,它会抛出
"CryptographicException: keyset not exist" (at line : durum response = proxy.getBatchStatus("1"(;
X509Certificate2 certificate = null;
X509Store store = new X509Store("MY", StoreLocation.CurrentUser);
store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
foreach (X509Certificate2 cert in collection)
{
if (cert.Subject.Contains("SERIALNUMBER=26635982214"))
{
if (cert.NotAfter > DateTime.Today)
{
certificate = cert;
}
}
}
CustomBinding binding = new CustomBinding();
AsymmetricSecurityBindingElement securityElement = (AsymmetricSecurityBindingElement)SecurityBindingElement.CreateMutualCertificateBindingElement(MessageSecurityVersion.WSSecurity10WSTrustFebruary2005WSSecureConversationFebruary2005WSSecurityPolicy11BasicSecurityProfile10);
securityElement.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
securityElement.IncludeTimestamp = true;
securityElement.EnableUnsecuredResponse = true;
securityElement.AllowInsecureTransport = true;
securityElement.SetKeyDerivation(false);
securityElement.KeyEntropyMode = SecurityKeyEntropyMode.CombinedEntropy;
securityElement.DefaultAlgorithmSuite = new CustomDefaultAlgorithmSuite();
securityElement.SecurityHeaderLayout = System.ServiceModel.Channels.SecurityHeaderLayout.Strict;
securityElement.RequireSignatureConfirmation = false;
X509SecurityTokenParameters x509ProtectionParameters = new X509SecurityTokenParameters(X509KeyIdentifierClauseType.IssuerSerial);
x509ProtectionParameters.InclusionMode = SecurityTokenInclusionMode.AlwaysToRecipient;
x509ProtectionParameters.X509ReferenceStyle = X509KeyIdentifierClauseType.RawDataKeyIdentifier;
x509ProtectionParameters.RequireDerivedKeys = false;
securityElement.InitiatorTokenParameters = x509ProtectionParameters;
binding.Elements.Add(securityElement);
binding.Elements.Add(new TextMessageEncodingBindingElement(MessageVersion.Soap12, Encoding.UTF8));
binding.Elements.Add(new HttpsTransportBindingElement());
AddressHeader[] addressHeaders = null;
EndpointAddress endpoint = new EndpointAddress(new Uri("https://uygtest.edefter.gov.tr/edefter/services/EDefterWSPort"), EndpointIdentity.CreateDnsIdentity("*.edefter.gov.tr"), addressHeaders);
EDefterWSClient proxy = new gibService.EDefterWSClient(binding, endpoint);
proxy.ClientCredentials.ClientCertificate.Certificate = certificate;
string serverCertFilePath = Path.Combine(Application.StartupPath, "edefter.gov.tr.crt");
proxy.ClientCredentials.ServiceCertificate.DefaultCertificate = new X509Certificate2(serverCertFilePath);
proxy.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = System.ServiceModel.Security.X509CertificateValidationMode.None;
durum response = proxy.getBatchStatus("1");
堆栈跟踪: konum: System.Security.Cryptography.Utils.CreateProvHandle(CspParameters parameters, Boolean randomKeyContainer( konum: System.Security.Cryptography.Utils.GetKeyPairHelper(CspAlgorithmType keyType, CspParameters parameters, Boolean randomKeyContainer, Int32 dwKeySize, SafeProvHandle& safeProvHandle, SafeKeyHandle&safeKeyHandle( konum: System.Security.Cryptography.RSACryptoServiceProvider.GetKeyPair(( konum: System.Security.Cryptography.RSACryptoServiceProvider..ctor(Int32 dwKeySize, CspParameters parameters, Boolean useDefaultKeySize( konum: System.IdentityModel.Tokens.X509AsymmetricSecurityKey.GetSignatureFormatter(String algorithm( konum: System.IdentityModel.SignedXml.ComputeSignature(SecurityKey signingKey( konum: System.ServiceModel.Security.WSSecurityOneDotZeroSendSecurityHeader.CompletePrimarySignatureCore(SendSecurityHeaderElement[] signatureConfirmations, SecurityToken[] signedEndorsingTokens, SecurityToken[] signedTokens, SendSecurityHeaderElement[] basicTokens, Boolean isPrimarySignature( konum: System.ServiceModel.Security.SendSecurityHeader.CompleteSignature(( konum: System.ServiceModel.Security.SendSecurityHeader.CompleteSecurityApplication(( konum: System.ServiceModel.Security.SecurityAppliedMessage.OnWriteMessage(XmlDictionaryWriter writer( konum: System.ServiceModel.Channels.BufferedMessageWriter.WriteMessage(Message message, BufferManager bufferManager, Int32 initialOffset, Int32 maxSizeQuota( konum: System.ServiceModel.Channels.TextMessageEncoderFactory.TextMessageEncoder.WriteMessage(Message message, Int32 maxMessageSize, BufferManager bufferManager, Int32 messageOffset( konum: System.ServiceModel.Channels.HttpOutput.SerializeBufferedMessage(Message message, Boolean shouldRecycleBuffer( konum: System.ServiceModel.Channels.HttpOutput.Send(TimeSpan timeout( konum: System.ServiceModel.Channels.HttpChannelFactory
1.HttpRequestChannel.HttpChannelRequest.SendRequest(Message message, TimeSpan timeout) konum: System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout) konum: System.ServiceModel.Channels.SecurityChannelFactory
1.SecurityRequestChannel.Request(Message message, TimeSpan timeout( konum: System.ServiceModel.Dispatcher.RequestChannelBinder.Request(Message message, TimeSpan timeout( konum: System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout( konum: System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation(konum: System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message(
public class CustomDefaultAlgorithmSuite : SecurityAlgorithmSuite
{
public override string DefaultAsymmetricKeyWrapAlgorithm
{
get { return SecurityAlgorithms.RsaOaepKeyWrap; }
}
public override string DefaultAsymmetricSignatureAlgorithm
{
get { return SecurityAlgorithms.RsaSha256Signature; }
}
public override string DefaultCanonicalizationAlgorithm
{
get { return SecurityAlgorithms.ExclusiveC14n; ; }
}
public override string DefaultDigestAlgorithm
{
get { return SecurityAlgorithms.Sha1Digest; }
}
public override string DefaultEncryptionAlgorithm
{
get { return SecurityAlgorithms.Aes128Encryption; }
}
public override int DefaultEncryptionKeyDerivationLength
{
get { return 128; }
}
public override int DefaultSignatureKeyDerivationLength
{
get { return 128; }
}
public override int DefaultSymmetricKeyLength
{
get { return 128; }
}
public override string DefaultSymmetricKeyWrapAlgorithm
{
get { return SecurityAlgorithms.Aes128Encryption; }
}
public override string DefaultSymmetricSignatureAlgorithm
{
get { return SecurityAlgorithms.HmacSha1Signature; }
}
public override bool IsAsymmetricKeyLengthSupported(int length)
{
return length >= 1024 && length <= 4096;
}
public override bool IsSymmetricKeyLengthSupported(int length)
{
return length >= 128 && length <= 256;
}
}
是否确定在当前用户存储中找到了带有SERIALNUMBER=26635982214
的证书?你没有任何检查。
另外,WCF 客户端在哪个用户下运行?检查您要查找的证书是否位于正确的存储中。
我认为您的问题是您的私钥存储在USB令牌/智能卡上,并且此私钥不可导出/提取或受PIN保护。因此,WCF 客户端不能使用此私钥对 SOAP 消息进行签名。
如果您的证书和私钥存储在 pfx 上,那么您可以如上所述调用此 WS,但在您的情况下,我认为无法使用 wcf 客户端对 soap 消息进行签名。