1

I am trying to implement XML signing with dot net 4.5 on windows server using sha 256 certificates . And I am getting - $exception "Invalid algorithm specified." . After googling I found that my NAP client has request policy as "Microsoft RSA Channel Cryptography Provider" and hash algorithm as SHA1RSA. Can I do any change in my code or use any other dlls to solve this issue?

    public class RSAPKCS1SHA256SignatureDescription :SignatureDescription
   {
  /// <summary>
    /// Registers the http://www.w3.org/2001/04/xmldsig-more#rsa-sha256 algorithm
    /// with the .NET CrytoConfig registry. This needs to be called once per
    /// appdomain before attempting to validate SHA256 signatures.
    /// </summary>
    public static void Register()
    {
        CryptoConfig.AddAlgorithm(
            typeof(RSAPKCS1SHA256SignatureDescription),
            "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
    }

    /// <summary>
    /// .NET calls this parameterless 
    /// </summary>
    public RSAPKCS1SHA256SignatureDescription()
    {
        KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider";
        DigestAlgorithm = "System.Security.Cryptography.SHA256Managed";
        FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
        DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
    }

    public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
    ![enter image description here][1] {
        var asymmetricSignatureDeformatter =
            (AsymmetricSignatureDeformatter)CryptoConfig.CreateFromName(DeformatterAlgorithm);
        asymmetricSignatureDeformatter.SetKey(key);
        asymmetricSignatureDeformatter.SetHashAlgorithm("SHA256");
        return asymmetricSignatureDeformatter;
    }

    public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
    {
        var asymmetricSignatureFormatter =
            (AsymmetricSignatureFormatter)CryptoConfig.CreateFromName(FormatterAlgorithm);
        asymmetricSignatureFormatter.SetKey(key);
        asymmetricSignatureFormatter.SetHashAlgorithm("SHA256");
        return asymmetricSignatureFormatter;
    }

}

     public String signExchangeRPmetadata(X509Certificate2 exchangeCerti)
    {

        string signatureCanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
        string signatureMethod = @"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
        string digestMethod = @"http://www.w3.org/2001/04/xmlenc#sha256";
        string signatureReferenceURI = " ";

        //For .NET 4.5 and above, SHA-256 support is, for the most part, built into the .NET framework. The only requirement is to register the cryptographic algorithm
        CryptoConfig.AddAlgorithm(typeof(RsaPkCs1Sha256SignatureDescription), signatureMethod);
        //CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription),"http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

        String path = "C:\\\\certificate\\certificate\\sha-256\\Exchange_RP.xml";
        XmlDocument exchangeAsRPXML = new XmlDocument();
        exchangeAsRPXML.Load(path);
        XmlNamespaceManager nameSpaceMgr = new XmlNamespaceManager(exchangeAsRPXML.NameTable);
        nameSpaceMgr.AddNamespace("ab", "urn:oasis:names:tc:SAML:2.0:metadata");

        CspParameters cspParams = new CspParameters(24); cspParams.KeyContainerName = "XML_DISG_RSA_KEY";
        RSACryptoServiceProvider key = new RSACryptoServiceProvider(cspParams); 
        key.FromXmlString(exchangeCerti.PrivateKey.ToXmlString(true));

        SignedXml signer = new SignedXml(exchangeAsRPXML);
        signer.SigningKey = exchangeCerti.PrivateKey;
        signer.KeyInfo = new KeyInfo();
        signer.KeyInfo.AddClause(new KeyInfoX509Data(exchangeCerti));

        signer.SignedInfo.CanonicalizationMethod = signatureCanonicalizationMethod;
        signer.SignedInfo.SignatureMethod = signatureMethod;

        XmlDsigEnvelopedSignatureTransform envelopeTransform = new XmlDsigEnvelopedSignatureTransform();
        XmlDsigExcC14NTransform cn14Transform = new XmlDsigExcC14NTransform();

        Reference signatureReference = new Reference();
        signatureReference.Uri = signatureReferenceURI;
        signatureReference.AddTransform(envelopeTransform);
        signatureReference.AddTransform(cn14Transform);
        signatureReference.DigestMethod = digestMethod;

        signer.AddReference(signatureReference);

        signer.ComputeSignature();
        XmlElement signatureElement = signer.GetXml();

        exchangeAsRPXML.DocumentElement.AppendChild(signer.GetXml());

        return null;
    }

Exception :

 at System.Security.Cryptography.CryptographicException.ThrowCryptographicException(Int32 hr)\r\n   at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash, Int32 cbHash, ObjectHandleOnStack retSignature)\r\n   at System.Security.Cryptography.Utils.SignValue(SafeKeyHandle hKey, Int32 keyNumber, Int32 calgKey, Int32 calgHash, Byte[] hash)\r\n   at System.Security.Cryptography.RSACryptoServiceProvider.SignHash(Byte[] rgbHash, Int32 calgHash)\r\n   at System.Security.Cryptography.RSAPKCS1SignatureFormatter.CreateSignature(Byte[] rgbHash)\r\n   at System.Security.Cryptography.AsymmetricSignatureFormatter.CreateSignature(HashAlgorithm hash)\r\n   at System.Security.Cryptography.Xml.SignedXml.ComputeSignature()\r\n   at ContactManager.Controllers.ProductController.signExchangeRPmetadata(X509Certificate2 exchangeCerti) 

References: Followed this stackoverflow thread

Community
  • 1
  • 1
  • It has been already implemented in [CLR Security](https://clrsecurity.codeplex.com/wikipage?title=Security.Cryptography.RSAPKCS1SHA256SignatureDescription&referringTitle=Security.Cryptography.dll). Just download and use the dlls in your project. – pepo Apr 30 '15 at 22:46
  • Thank you @pepo do I need to change any thing on the Request Policy side ? Any change required with Windows : Cryptography Service provider side? – user3512128 Apr 30 '15 at 23:27
  • No, just sign the xml like you usually do. – pepo May 01 '15 at 06:54
  • Has this been sufficiently answered within the comments? – Maarten Bodewes May 09 '15 at 00:28
  • This answer is kind of right. However, as I am using dot net 4.5 hence those libs are already present. The reason for my signature failure was missing sha256 attribute in the openssl command. I used the following command to solve the issue. openssl req -x509 -sha256 -nodes -days 1826 -newkey rsa:2048 -keyout congov-dev-key.key -out congov-dev-cert.crt openssl pkcs12 -export -out congov-dev.pfx -inkey congov-dev-key.key -in congov-dev-cert.crt – user3512128 May 11 '15 at 16:23

0 Answers0