4

I need to sign (and verify eventually) one of the nodes of an XML document using RSA-SHA1 algorithm. w3.org link

RSA-SHA1 URI:
http://www.w3.org/2000/09/xmldsig#rsa-sha1
Specified in:
section 6.4.2 of [XMLDSIG-CORE2002]

I am following this example, however cannot figure how to change the algorithm to required.

The signature generation happens here:

signedXml.ComputeSignature();

The only override with a parameter expects KeyedHashAlgorithm:

public void ComputeSignature(KeyedHashAlgorithm macAlg); (link)

KeyedHashAlgorithm (link) in turn only allows creating HMAC* and MAC* algorithms and has no RSA-SHA1.

What is the most painless way of signing an XML with RSA-SHA1 in .Net?

Edit:

I'm trying to use a X509 certificate to extract the key. Certificate's signature algorithm property is sha1RSA.

This is how I'm assigning it:

var signedXml = new SignedXml(xmlDoc);
...
signedXml.SigningKey = (RSACryptoServiceProvider)cert.PrivateKey;
...
signedXml.ComputeSignature();

The resulting signature xml format matches expected one, however digest and signature values are invalid.

user5226582
  • 1,946
  • 1
  • 22
  • 37

1 Answers1

16

In .NET Framework 1.1 through .NET Framework 4.7 you get RSA-SHA-1 by simply setting signedXml.SigningKey to an RSA key object.

If .NET 4.7.1 (currently in preview) is installed the default for RSA will change to RSA-SHA-2-256, per https://github.com/Microsoft/dotnet/blob/master/releases/net471/dotnet471-changes.md.

So, if you really want a RSA-SHA-1 signature you need to

a) set signedXml.SigningKey to an RSA key

b) set signedXml.SignedInfo.SignatureMethod = SignedXml.XmlDsigRSASHA1Url

(both before calling signedXml.ComputeSignature())

Conversely, if you want to do something better than RSA-SHA-1 on current versions, set signedXml.SignedInfo.SignatureMethod to SignedXml.XmlDsigSHA256Url or better.


Word of warning: SHA-1 is considered broken for cryptographic purposes now that a collision has been found. While it's not generalized enough (at this point) to attack arbitrary XML, it may well grow up to that point. You really shouldn't be using SHA-1 in anything new, and should consider validating that your signature method is something better than SHA-1 based when deciding whether to accept a signed document.

bartonjs
  • 30,352
  • 2
  • 71
  • 111
  • 1
    @user5226582 Ah, SignedXml.SignatureMethod is a readonly projection of the writable SignedXml.SignatureInfo.SignatureMethod. Fixed the answer. – bartonjs Sep 07 '17 at 13:29
  • 1
    @bartonjs, should not it has a third 'c' item for `reference.DigestMethod = SignedXml.XmlDsigSHA1Url`? Or isn't that step really necessary for all types of SHA-1 XML signing? – Pedro Gaspar Nov 27 '18 at 12:58
  • 1
    @PedroGaspar If you want all-SHA-1, then yes. But the digest for the references and the digest used in the signature don't need to match. – bartonjs Nov 27 '18 at 15:41