none
Invalid algorithm specified RRS feed

  • Question

  • Hi,

    I'm trying to sign documents with Xades. I use SignedXml, when i signing the file with default sha (sha1) works but I want to change SignatureMethod to use sha256 I'm doing this : 

    ...

     CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");

      xml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";

    and when i call xml.ComputeSignature();

    i have this error 

    Invalid algorithm specified

    ...

     

    public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
            {
                public RSAPKCS1SHA256SignatureDescription()
                {

                    base.KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider";
                    base.DigestAlgorithm = "System.Security.Cryptography.SHA256Managed";
                    base.FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
                    base.DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
                }

                public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
                {
                    if (key == null)
                        throw new ArgumentNullException("key");

                    RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
                    deformatter.SetHashAlgorithm("SHA256");
                    return deformatter;
                }

                public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
                {
                    if (key == null)
                        throw new ArgumentNullException("key");

                    RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
                    formatter.SetHashAlgorithm("SHA256");
                    return formatter;
                }
            }

                    
    Tuesday, July 31, 2012 9:23 PM

All replies

  • Hi Ja,

    Welcome to the MSDN Forum.

    How about this blog: http://blogs.msdn.com/b/alejacma/archive/2010/05/25/invalid-algorithm-specified-when-signing-with-rsacryptoserviceprovider-and-sha-256.aspx 

    Remember that SHA 256 support depends on the CSP you are using, like I explained on this post (which also applies to versions of Windows newer than XP): SHA-2 support on Windows XP.

    In this case, the only solution is to talk to the providers of the CSP to ask for SHA 256 support, or change to another CSP.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, August 1, 2012 8:55 AM
    Moderator
  • Hi,

    I'm using a Microsoft CSP... I have 'Invalid algorithm specified' on CreateSignature(hash);

    public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
            {
                public RSAPKCS1SHA256SignatureDescription()
                {
                    KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
                    DigestAlgorithm = typeof(SHA256Managed).FullName;   // Note - SHA256CryptoServiceProvider is not registered with CryptoConfig
                    FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName;
                    DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName;
                }

                public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
                {
                    if (key == null)
                        throw new ArgumentNullException("key");

                    RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
                    deformatter.SetHashAlgorithm("SHA256");
                    return deformatter;
                }

                public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
                {
                    if (key == null)
                        throw new ArgumentNullException("key");

                    RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
                    formatter.SetHashAlgorithm("SHA256");
                    
                    return formatter;
                }
            }

    {

                this.BuildDigestedReferences();
                AsymmetricAlgorithm signingKey = this.SigningKey;
                if (signingKey == null)
                {
                    throw new CryptographicException("Cryptography_Xml_LoadKeyFailed");
                }
                if (this.SignedInfo.SignatureMethod == null)
                {
                    if (!(signingKey is DSA))
                    {
                        if (!(signingKey is RSA))
                        {
                            throw new CryptographicException("Cryptography_Xml_CreatedKeyFailed");
                        }
                        if (this.SignedInfo.SignatureMethod == null)
                        {
                            this.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig-more#rsa-sha256";
                        }
                    }
                    else
                    {
                        this.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig-more#rsa-sha256";
                    }
                }
                CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2000/09/xmldsig-more#rsa-sha256");
                
                
                SignatureDescription description = CryptoConfig.CreateFromName("http://www.w3.org/2000/09/xmldsig-more#rsa-sha256") as SignatureDescription;
                if (description == null)
                {
                    throw new CryptographicException("Cryptography_Xml_SignatureDescriptionNotCreated");
                }
                HashAlgorithm hash = description.CreateDigest();
                if (hash == null)
                {
                    throw new CryptographicException("Cryptography_Xml_CreateHashAlgorithmFailed");
                }
                //this.GetC14NDigest(hash);
                this.GetC14NDigest(hash, "ds");
                
                
                this.m_signature.SignatureValue = description.CreateFormatter(signingKey).CreateSignature(hash);

    }

    Wednesday, August 1, 2012 2:01 PM
  • Please can anyone help?
    Wednesday, August 1, 2012 9:19 PM
  • Hi Jaferrira,

    How would I handle this code:

    {
    
                this.BuildDigestedReferences();
                AsymmetricAlgorithm signingKey = this.SigningKey;
                if (signingKey == null)
                {
                    throw new CryptographicException("Cryptography_Xml_LoadKeyFailed");
                }
                if (this.SignedInfo.SignatureMethod == null)
                {
                    if (!(signingKey is DSA))
                    {
                        if (!(signingKey is RSA))
                        {
                            throw new CryptographicException("Cryptography_Xml_CreatedKeyFailed");
                        }
                        if (this.SignedInfo.SignatureMethod == null)
                        {
                            this.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig-more#rsa-sha256";
                        }
                    }
                    else
                    {
                        this.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig-more#rsa-sha256";
                    }
                }
                CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2000/09/xmldsig-more#rsa-sha256");
                
                
                SignatureDescription description = CryptoConfig.CreateFromName("http://www.w3.org/2000/09/xmldsig-more#rsa-sha256") as SignatureDescription;
                if (description == null)
                {
                    throw new CryptographicException("Cryptography_Xml_SignatureDescriptionNotCreated");
                }
                HashAlgorithm hash = description.CreateDigest();
                if (hash == null)
                {
                    throw new CryptographicException("Cryptography_Xml_CreateHashAlgorithmFailed");
                }
                //this.GetC14NDigest(hash);
                this.GetC14NDigest(hash, "ds");
                
                
                this.m_signature.SignatureValue = description.CreateFormatter(signingKey).CreateSignature(hash);
    }

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, August 2, 2012 2:58 AM
    Moderator
  • I'm using http://www.microsoft.com/france/interop/ressources/xades.aspx i just change framework to 4.0
    Thursday, August 2, 2012 8:16 AM
  • Hi Jaferrira,

    I have downloaded the sample, please show me the details steps to reproduce your issue. Thank you very much.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, August 3, 2012 2:49 AM
    Moderator
  • Hi Mike,

    First you need to change the XadesSignXml to use SHA256.

    You need do add this function 

    public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
            {
                public RSAPKCS1SHA256SignatureDescription()
                {
                    KeyAlgorithm = typeof(RSACryptoServiceProvider).FullName;
                    DigestAlgorithm = typeof(SHA256Managed).FullName;   // Note - SHA256CryptoServiceProvider is not registered with CryptoConfig
                    FormatterAlgorithm = typeof(RSAPKCS1SignatureFormatter).FullName;
                    DeformatterAlgorithm = typeof(RSAPKCS1SignatureDeformatter).FullName;
                }

                public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
                {
                    if (key == null)
                        throw new ArgumentNullException("key");

                    RSAPKCS1SignatureDeformatter deformatter = new RSAPKCS1SignatureDeformatter(key);
                    deformatter.SetHashAlgorithm("SHA256");
                    return deformatter;
                }

                public override AsymmetricSignatureFormatter CreateFormatter(AsymmetricAlgorithm key)
                {
                    if (key == null)
                        throw new ArgumentNullException("key");

                    RSAPKCS1SignatureFormatter formatter = new RSAPKCS1SignatureFormatter(key);
                    formatter.SetHashAlgorithm("SHA256");
                    
                    return formatter;
                }
            }

    And need change ComputeSignature() to : 

    public new void ComputeSignature(){

     this.BuildDigestedReferences();
                AsymmetricAlgorithm signingKey = this.SigningKey;
                if (signingKey == null)
                {
                    throw new CryptographicException("Cryptography_Xml_LoadKeyFailed");
                }
                if (this.SignedInfo.SignatureMethod == null)
                {
                    if (!(signingKey is DSA))
                    {
                        if (!(signingKey is RSA))
                        {
                            throw new CryptographicException("Cryptography_Xml_CreatedKeyFailed");
                        }
                        if (this.SignedInfo.SignatureMethod == null)
                        {
                            this.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig-more#rsa-sha256";
                        }
                    }
                    else
                    {
                        this.SignedInfo.SignatureMethod = "http://www.w3.org/2000/09/xmldsig-more#rsa-sha256";
                    }
                }
                CryptoConfig.AddAlgorithm(typeof(RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2000/09/xmldsig-more#rsa-sha256");
                
                
                SignatureDescription description = CryptoConfig.CreateFromName("http://www.w3.org/2000/09/xmldsig-more#rsa-sha256") as SignatureDescription;
                if (description == null)
                {
                    throw new CryptographicException("Cryptography_Xml_SignatureDescriptionNotCreated");
                }
                HashAlgorithm hash = description.CreateDigest();
                if (hash == null)
                {
                    throw new CryptographicException("Cryptography_Xml_CreateHashAlgorithmFailed");
                }
                //this.GetC14NDigest(hash);
                this.GetC14NDigest(hash, "ds");
                
                
                this.m_signature.SignatureValue = description.CreateFormatter(signingKey).CreateSignature(hash);
    }

    For testing you need to run TestClient and following the steps :

    - On select Document Tab -> just click once on Add Reference ( after this you see 'Next Object Id Suffix : 2' )

    - On Select Certificate -> you need to select one certificate

    - Last you need to open Sign tab and click on Compute Signature

    Thank you

    Friday, August 3, 2012 8:40 AM
  • Hi Jaferrira,

    Thank you for your clarifications.

    I have reproduced this scenario. Based on my test, this is related to the algorithm how the certificate generated, I tried your way, indeed I got a "Invaild algorithm specified", but I change the function ComputeSignature to the original one, and it works fine.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, August 9, 2012 2:38 AM
    Moderator
  • But works with SHA1 no ? 

    I need SHA256 or SHA512

    Monday, August 27, 2012 4:37 PM
  • Ja. Ferreria ,

    I have the exact same scenario with SHA 256 . I am follwing this http://social.msdn.microsoft.com/Forums/en-SG/netfxbcl/thread/6438011b-92fb-4123-a22f-ad071efddf85 .and I am unable to register SHA 256 description in sharepoint 2010 as it is based on .Net 3.5.

    I am able to do this in my Test windows application where I have .Net fraework 4.0 and the Cryptoconfig works and has the Addlgorith method available to add an algorthm's descrition.

    Please let me know if you have found a workaround to sign an xml with SHA 256 in sharepoint.

    Thanks


    MUneeb

    Monday, October 1, 2012 4:01 PM
  • Ja. Ferreria ,

    I have the exact same scenario with SHA 256 . I am follwing this http://social.msdn.microsoft.com/Forums/en-SG/netfxbcl/thread/6438011b-92fb-4123-a22f-ad071efddf85 .and I am unable to register SHA 256 description in sharepoint 2010 as it is based on .Net 3.5.

    I am able to do this in my Test windows application where I have .Net fraework 4.0 and the Cryptoconfig works and has the Addlgorith method available to add an algorthm's descrition.

    Please let me know if you have found a workaround to sign an xml with SHA 256 in sharepoint.

    Thanks


    MUneeb

    Hi,

    No i dont have any workaround but i'm working on it..... Can you show the code of your test project that works please?

    Thanks

    Tuesday, October 2, 2012 4:01 PM
  •  
    These are the two methods to get a certificate and do the signing.......
    
    
    
    
    
     void SignData()
            {
    
    
                try
            {
                // Create a new CspParameters object to specify 
                // a key container.
                CspParameters cspParams = new CspParameters();
    
    
                X509Store store = new X509Store(StoreName.My, StoreLocation.LocalMachine);
                try
                {
                    store.Open(OpenFlags.ReadOnly);
                }
                catch (Exception ex)
                {
                    throw new Exception("Error opening certificate store", ex);
                }
    
                RSACryptoServiceProvider csp = null;
                    string key= "";
    
                    X509Certificate2 cert=null;
                foreach (X509Certificate2 certs in store.Certificates)
                {
    
                    if (certs.HasPrivateKey)
                    {
                        if (certs.FriendlyName.ToString() == "certificatename")
                        {
    
                            csp = (RSACryptoServiceProvider)certs.PrivateKey;
    
                            cert = certs;
    
                        }
                    }
                }
    
                    
    
                    cspParams.KeyContainerName=key;
    
    
    
    
             //   cspParams.KeyContainerName = "XML_DSIG_RSA_KEY";
    
                // Create a new RSA signing key and save it in the container. 
                RSACryptoServiceProvider rsaKey = new RSACryptoServiceProvider(cspParams);
    
                // Create a new XML document.
                XmlDocument xmlDoc = new XmlDocument();
    
                // Load an XML file into the XmlDocument object.
                xmlDoc.PreserveWhitespace = true;
                xmlDoc.Load(@"C:\Users\WindowsFormsApplication1\test1.xml");
    
                // Sign the XML document. 
                SignXml(xmlDoc, rsaKey,cert);
    
                Console.WriteLine("XML file signed.");
    
                // Save the document.
                xmlDoc.Save("test.xml");
    
                    
    
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    
    
    Method to SIGN the XML document.....
    
            public static void SignXml(XmlDocument xmlDoc, RSA Key, X509Certificate2 cert)
        {
    
           // XmlNamespaceManager ns = new XmlNamespaceManager(xmlDoc.NameTable); ns.AddNamespace("SOAP", STR_SOAP_NS); ns.AddNamespace("SOAP-SEC", STR_SOAPSEC_NS);
    
    
            
            // Check arguments. 
            if (xmlDoc == null)
                throw new ArgumentException("xmlDoc");
            if (Key == null)
                throw new ArgumentException("Key");
    
            CryptoConfig.AddAlgorithm(typeof(Security.Cryptography.RSAPKCS1SHA256SignatureDescription), "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256");
     
                
    
            // Create a SignedXml object.
            SignedXml signedXml = new SignedXml(xmlDoc);
    
            signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
                
    
            KeyInfo keyInfo = new KeyInfo(); 
                // *** The actual key for signing - MAKE SURE THIS ISN'T NULL!
           signedXml.SigningKey = cert.PrivateKey;    
                // *** Specifically use the issuer and serial number for the data rather than the default  
           KeyInfoX509Data keyInfoData = new KeyInfoX509Data();  
             //   keyInfoData.AddIssuerSerial(cert.Issuer, cert.GetSerialNumberString());
                keyInfoData.AddCertificate(cert);
                keyInfo.AddClause(keyInfoData);   
                // *** provide the certficate info that gets embedded - note this is only    // *** for specific formatting of the message to provide the cert info  
                signedXml.KeyInfo = keyInfo;
    
               
    
            // Add the key to the SignedXml document.
            signedXml.SigningKey = Key;
    
            // Create a reference to be signed.
            Reference reference = new Reference();
            reference.Uri = "";
    
            // Add an enveloped transformation to the reference.
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();
          //  env.Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#";
            reference.AddTransform(env);
    
            XmlDsigEnvelopedSignatureTransform env1 = new XmlDsigEnvelopedSignatureTransform();
            env1.Algorithm = "http://www.w3.org/2001/10/xml-exc-c14n#";
    
            reference.AddTransform(env1);
            // Add the reference to the SignedXml object.
            signedXml.AddReference(reference);
    
    
           signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha256";
    
         //  signedXml.SignedInfo.SignatureMethod = "http://www.w3.org/2001/04/xmldsig-more#rsa-sha384";
            // Compute the signature.
            signedXml.ComputeSignature();
    
            // Get the XML representation of the signature and save 
            // it to an XmlElement object.
            XmlElement xmlDigitalSignature = signedXml.GetXml();
    
    
            XmlNamespaceManager nmgr = new XmlNamespaceManager(xmlDoc.NameTable);
                          XmlElement node = xmlDoc.DocumentElement.SelectSingleNode("//s:Envelope/s:Header/wsse:Security", nmgr) as XmlElement;
    
            XmlElement oldnode = xmlDoc.DocumentElement.SelectSingleNode("//s:Envelope/s:Header", nmgr) as XmlElement; ;
    
            node.AppendChild(xmlDigitalSignature);
    
          //  xmlDoc.ReplaceChild(node, oldnode);
    
            xmlDoc.SelectSingleNode("//s:Envelope/s:Header/wsse:Security", nmgr).AppendChild(xmlDigitalSignature);
    
           // XmlElement soapHeader = xmlDoc.DocumentElement.SelectSingleNode("//SOAP:Header", ns) as XmlElement;
    
            XmlNodeList nodes = xmlDoc.DocumentElement.GetElementsByTagName("Issuer");
            nodes[0].ParentNode.InsertAfter(xmlDoc.ImportNode(signedXml.GetXml(), true), nodes[0]); 
    
            // Append the element to the XML document.
            xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));
    
        }
    }
    
    
    
    
    
    
    And this is the class I have added to my application...
    
    
    using System.Security.Cryptography;
    
    
    namespace Security.Cryptography
    
    {
        public class RSAPKCS1SHA256SignatureDescription : SignatureDescription
        {
            public RSAPKCS1SHA256SignatureDescription()
            {
                base.KeyAlgorithm = "System.Security.Cryptography.RSACryptoServiceProvider";
                base.DigestAlgorithm = "System.Security.Cryptography.SHA256Managed";
                base.FormatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureFormatter";
                base.DeformatterAlgorithm = "System.Security.Cryptography.RSAPKCS1SignatureDeformatter";
            }
    
            public override AsymmetricSignatureDeformatter CreateDeformatter(AsymmetricAlgorithm key)
            {
                AsymmetricSignatureDeformatter asymmetricSignatureDeformatter = (AsymmetricSignatureDeformatter)
                    CryptoConfig.CreateFromName(base.DeformatterAlgorithm);
                asymmetricSignatureDeformatter.SetKey(key);
                asymmetricSignatureDeformatter.SetHashAlgorithm("SHA256");
                return asymmetricSignatureDeformatter;
            }
        }
    
    }
    
    
    Remember this works in .Net 4.0 and not in .Net 3.5 on which Sharepoint in built on. Let me know if this helps and you come across anything helpful for me.
    
    Thanks


    MUneeb

    Tuesday, October 2, 2012 7:12 PM