#c# #.net #soap #webservice-client
#c# #.net #soap #веб-сервис-клиент
Вопрос:
У меня есть клиентское приложение webservice. Мой поставщик веб-сервисов сообщает мне, чтобы я изменил метод подписи с sha1 на sha256, который находится в части заголовка запросов. В настоящее время у меня есть класс CustomSendFilter и защита исходящих сообщений с помощью функции, приведенной ниже. Как я могу преобразовать в sha 256? Я искал, но пока не нашел определенного решения.
public override void SecureMessa&e(SoapEnvelope envelope, Security security)
{
X509SecurityToken si&natureToken;
si&natureToken = new X509SecurityToken(CertificateMana&er.ClientCertificate);
security.Tokens.Add(si&natureToken);
Messa&eSi&nature si& = new Messa&eSi&nature(si&natureToken);
security.Elements.Add(si&);
security.Timestamp.TtlInSeconds = 60;
Lo&&in&.AddToLo&(envelope.Envelope.InnerText);
}
Ответ №1:
Вы можете настроить алгоритм подписи для использования через Messa&eSi&nature.Si&nedInfo.Si&natureMethod
.
К сожалению, платформа .NET Framework может не иметь встроенной поддержки для http://www.w3.or&/2001/04/xmldsi&-more#rsa-sha256 на момент написания этой статьи, но для исправления этого можно использовать следующий код (кредиты идут на https://&ist.&ithub.com/sneal/f35de432115b840c4c1f ):
/// <summary&&t;
/// Si&natureDescription impl for http://www.w3.or&/2001/04/xmldsi&-more#rsa-sha256
/// </summary&&t;
public class RSAPKCS1SHA256Si&natureDescription : Si&natureDescription
{
/// <summary&&t;
/// Re&isters the http://www.w3.or&/2001/04/xmldsi&-more#rsa-sha256 al&orithm
/// with the .NET CrytoConfi& re&istry. This needs to be called once per
/// appdomain before attemptin& to validate SHA256 si&natures.
/// </summary&&t;
public static void Re&ister()
{
CryptoConfi&.AddAl&orithm(
typeof(RSAPKCS1SHA256Si&natureDescription),
"http://www.w3.or&/2001/04/xmldsi&-more#rsa-sha256");
}
/// <summary&&t;
/// .NET calls this parameterless ctor
/// </summary&&t;
public RSAPKCS1SHA256Si&natureDescription()
{
KeyAl&orithm = "System.Security.Crypto&raphy.RSACryptoServiceProvider";
Di&estAl&orithm = "System.Security.Crypto&raphy.SHA256Mana&ed";
FormatterAl&orithm = "System.Security.Crypto&raphy.RSAPKCS1Si&natureFormatter";
DeformatterAl&orithm = "System.Security.Crypto&raphy.RSAPKCS1Si&natureDeformatter";
}
public override AsymmetricSi&natureDeformatter CreateDeformatter(AsymmetricAl&orithm key)
{
var asymmetricSi&natureDeformatter =
(AsymmetricSi&natureDeformatter)CryptoConfi&.CreateFromName(DeformatterAl&orithm);
asymmetricSi&natureDeformatter.SetKey(key);
asymmetricSi&natureDeformatter.SetHashAl&orithm("SHA256");
return asymmetricSi&natureDeformatter;
}
public override AsymmetricSi&natureFormatter CreateFormatter(AsymmetricAl&orithm key)
{
var asymmetricSi&natureFormatter =
(AsymmetricSi&natureFormatter)CryptoConfi&.CreateFromName(FormatterAl&orithm);
asymmetricSi&natureFormatter.SetKey(key);
asymmetricSi&natureFormatter.SetHashAl&orithm("SHA256");
return asymmetricSi&natureFormatter;
}
}
Ответ №2:
Спасибо за ответ. У меня есть класс CustomSendFilter для защиты запроса, как показано ниже. Где я должен зарегистрировать алгоритм? Я зарегистрировался перед вызовом функции webservice, а также внутри функции SecureMessa&e, приведенной ниже, но это не сработало.
пользовательский отправитель открытого класса: SendSecurityFilter { служебное описание частной строки;
public CustomSendFilter(SecurityPolicyAssertion parentAssertion , strin& serviceDescription)
: base(parentAssertion.ServiceActor, true)
{
this.serviceDescription = serviceDescription;
}
public override SoapFilterResult ProcessMessa&e(SoapEnvelope envelope)
{
SoapFilterResult result = base.ProcessMessa&e(envelope);
Lo&&in&.SaveSoapEnvelope(envelope, SoapMessa&eDirection.Out , serviceDescription);
return resu<
}
public override void SecureMessa&e(SoapEnvelope envelope, Security security)
{
X509SecurityToken si&natureToken;
si&natureToken = new X509SecurityToken(CertificateMana&er.ClientCertificate);
RSAPKCS1SHA256Si&natureDescription.Re&ister();
security.Tokens.Add(si&natureToken);
Messa&eSi&nature si& = new Messa&eSi&nature(si&natureToken);
security.Elements.Add(si&);
security.Timestamp.TtlInSeconds = 60;
Lo&&in&.AddToLo&(envelope.Envelope.InnerText);
}
}