none
Digital sign From SHA1 to SHA256

    Question

  • Hello, I'm trying to update a function that performs a digital signature, I want to switch from SHA1 to SHA256 this is the current function:

    private byte[] zSignData(Byte[] msg, X509Certificate2 signerCert)
    {
    ContentInfo contentInfo = new ContentInfo(msg);
    SignedCms signedCms = new SignedCms(contentInfo, false);
    CmsSigner cmsSigner = new CmsSigner(signerCert);

    cmsSigner
    .DigestAlgorithm = new Oid("1.3.14.3.2.26"); //SHA1

    signedCms
    .ComputeSignature(cmsSigner, false);

    return signedCms.Encode();
    }

    this function work well

    To update to SHA256, I changed

    cmsSigner.DigestAlgorithm = new Oid("1.3.14.3.2.26"); //SHA1

    with

    cmsSigner.DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1");//SHA256

    but at

    signedCms.ComputeSignature(cmsSigner, false);

    I get the following exception System.Security.Cryptography.CryptographicException Message=There was an internal error.

    (InnerException is null and no message in eventviewer)

    someone has a suggestion?

    I work with VS2010 Professional 64 and win7 professional 64 and  I installed the crypto service provider CSP provided with the smart card.

    many thanks


    • Changed type nmontero Wednesday, April 20, 2011 12:36 PM
    Wednesday, April 20, 2011 12:36 PM

All replies

  • Hi nmontero,

    Thank you for your question. 

    I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.

    Thank you for your understanding and support.

    Best Regards,


    Larcolais Gong[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Thursday, April 21, 2011 3:04 AM
  • Hi nmontero,

    try without sending any true/false as a ComputerSignature parameter as:

    signedCms.ComputeSignature(cmsSigner);


    Regards, http://shwetamannjain.blogspot.com
    • Proposed as answer by Shweta Jain (Lodha) Thursday, April 21, 2011 8:01 AM
    • Unproposed as answer by nmontero Thursday, April 21, 2011 8:15 AM
    Thursday, April 21, 2011 5:31 AM
  • Hi Larcolais,

    Yes of course, I will be patient.

    Many thanks for your support

    Thursday, April 21, 2011 8:00 AM
  • Hi Shweta,

    Many thanks for your replay, I tried your suggestion but the behavior is the same.

    Thursday, April 21, 2011 8:02 AM
  • This is a known issue. We don’t officially support the CMS classes with SHA-2 (the only official .NET RSA-SHA2 implementation is the raw RSACryptoServiceProvider one in .NET 3.5 SP1) algorithms.  Your code won’t work on Windows Vista and later with third-party CSPs. Here is a blog related to this issue:

    "An internal error occurred" when using SHA-2 algorithms with SignedCMS
    http://blogs.msdn.com/b/alejacma/archive/2010/06/02/quot-an-internal-error-ocurred-quot-when-using-sha-2-algorithms-with-signedcms.aspx


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"
    Monday, April 25, 2011 3:16 PM
    Owner
  • This is a known issue. We don’t officially support the CMS classes with SHA-2 (the only official .NET RSA-SHA2 implementation is the raw RSACryptoServiceProvider one in .NET 3.5 SP1) algorithms.  Your code won’t work on Windows Vista and later with third-party CSPs. Here is a blog related to this issue:

    "An internal error occurred" when using SHA-2 algorithms with SignedCMS
    http://blogs.msdn.com/b/alejacma/archive/2010/06/02/quot-an-internal-error-ocurred-quot-when-using-sha-2-algorithms-with-signedcms.aspx


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"


    Hi Trevor,

    So in summary, CAPI2 support SHA256 only with a CNG CSP but SignedCMS not support CNG.
    So it is not possible sign with SHA256 as hash algorithm.

    Do you know if the support of SignedCMS and CNG Provider is in same road map?

     

    Tuesday, April 26, 2011 9:20 AM
  • This is a known issue. We don’t officially support the CMS classes with SHA-2 (the only official .NET RSA-SHA2 implementation is the raw RSACryptoServiceProvider one in .NET 3.5 SP1) algorithms.  Your code won’t work on Windows Vista and later with third-party CSPs. Here is a blog related to this issue:

    "An internal error occurred" when using SHA-2 algorithms with SignedCMS
    http://blogs.msdn.com/b/alejacma/archive/2010/06/02/quot-an-internal-error-ocurred-quot-when-using-sha-2-algorithms-with-signedcms.aspx


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"


    Hi Trevor,

    So in summary, CAPI2 support SHA256 only with a CNG CSP but SignedCMS not support CNG.
    So it is not possible sign with SHA256 as hash algorithm.

    Do you know if the support of SignedCMS and CNG Provider is in same road map?

     


    sorry, wrong live ID

    Hi Trevor,

    So in summary, CAPI2 support SHA256 only with a CNG CSP but SignedCMS not support CNG.
    So it is not possible sign with SHA256 as hash algorithm.

    Do you know if the support of SignedCMS and CNG Provider is in same road map?

     

    Tuesday, April 26, 2011 9:57 AM
  • 1.  So in summary, CAPI2 support SHA256 only with a CNG CSP but SignedCMS does not support CNG.

    Alex stated in his blog that “SignedCMS class doesn't support CNG”.


    2. So it is not possible to sign with SHA256 as hash algorithm.

    The only official .NET RSA-SHA2 implementation is the raw RSACryptoServiceProvider one in .NET 3.5 SP1

     

    Example:

        byte[] data = new byte[] { 0, 1, 2, 3, 4, 5 };

        SHA256CryptoServiceProvider hash = new SHA256CryptoServiceProvider();

        byte[] hashedData;

        RSAParameters rsaPrivateParams;

        rsaPrivateParams = rsaCSP.ExportParameters(true);

         rsaCSP.ImportParameters(rsaPrivateParams);

        hashedData = hash.ComputeHash(data);

         string sha256Oid = CryptoConfig.MapNameToOID("SHA256");

        byte[] signature = rsaCSP.SignHash(hashedData, sha256Oid);

     

    3.  Do you know if the support of SignedCMS and CNG Provider is in same road map?

    The question is not clear to me. I will refer back to the answer to question# 1 above.

     


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"
    Monday, May 02, 2011 7:43 PM
    Owner
  • 1.  So in summary, CAPI2 support SHA256 only with a CNG CSP but SignedCMS does not support CNG.

    Alex stated in his blog that “SignedCMS class doesn't support CNG”.


    2. So it is not possible to sign with SHA256 as hash algorithm.

    The only official .NET RSA-SHA2 implementation is the raw RSACryptoServiceProvider one in .NET 3.5 SP1

     

    Example:

        byte[] data = new byte[] { 0, 1, 2, 3, 4, 5 };

        SHA256CryptoServiceProvider hash = new SHA256CryptoServiceProvider();

        byte[] hashedData;

        RSAParameters rsaPrivateParams;

        rsaPrivateParams = rsaCSP.ExportParameters(true);

         rsaCSP.ImportParameters(rsaPrivateParams);

        hashedData = hash.ComputeHash(data);

         string sha256Oid = CryptoConfig.MapNameToOID("SHA256");

        byte[] signature = rsaCSP.SignHash(hashedData, sha256Oid);

     

    3.  Do you know if the support of SignedCMS and CNG Provider is in same road map?

    The question is not clear to me. I will refer back to the answer to question# 1 above.

     


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"


    Many thanks for this replay,

    so, I can sign, and then manually create a valid SignedCms. May you so kind as to tell me some links on how to manually create a SignedCms?  Many thanks

    Tuesday, May 03, 2011 10:45 AM
  • Try this and let me know:

     

    using System;
    using System.Security.Cryptography;
    using System.Security.Cryptography.Pkcs;
    using System.Security.Cryptography.X509Certificates;
    
    namespace TestSHA256Signature
    {
      class Program
      {
        static void Main(string[] args)
        {
          byte[] data = { 1, 2, 3, 4, 5 };
          byte[] signed = null;
    
          signed = SignBuffer(data);
    
          bool valid = Verify(data, signed);
        }
    
        static byte[] SignBuffer(byte[] data)
        {
          byte[] signedData = null;
    
          try
          {
            X509Certificate2 cert = null;
            X509Store keyStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            try
            {
              keyStore.Open(OpenFlags.ReadOnly);
    
              X509Certificate2Collection certs = keyStore.Certificates.Find(X509FindType.FindByThumbprint, "babdf76c001a76256d8ed9a96e4cead0c6a9e2c8", false);
              if (certs != null && certs.Count > 0)
                cert = certs[0];
            }
            finally
            {
              keyStore.Close();
            }
    
            CmsSigner cmsSigner = new CmsSigner(cert);
            cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;
            cmsSigner.DigestAlgorithm = new Oid("SHA256");
            SignedCms signedCms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber, new ContentInfo(data), true);
            signedCms.ComputeSignature(cmsSigner, false);
            signedData = signedCms.Encode();
          }
          catch (CryptographicException e)
          {
            Console.WriteLine("Signing failed: " + e.ToString());
          }
          return signedData;
        }
    
        static bool Verify(byte[] data, byte[] signedData)
        {
          try
          {
            SignedCms signedCms = new SignedCms(new ContentInfo(data), true);
            signedCms.Decode(signedData);
            signedCms.CheckSignature(false); 
    
            return true;
          }
          catch (CryptographicException e)
          {
            Console.WriteLine("Verify failed: " + e.ToString());
          }
          return false;
        }
    
      }
    }
    


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"
    Tuesday, May 03, 2011 8:43 PM
    Owner
  • Maybe I'm doing this wrong, but this is the code that I use for doing SHA2:

        public static byte[] ComputeHash(string data, string salt = "")
        {
          using (var provider = SHA512.Create())
          {
            var input = string.Format(CultureInfo.InvariantCulture, "{0}{1}",
              data, salt ?? string.Empty);
            var inputBytes = Encoding.Unicode.GetBytes(input);
            var hashBytes = provider.ComputeHash(inputBytes);
            return hashBytes;
          }
        }
    
    Evan
    Tuesday, May 03, 2011 8:55 PM
  • Try this and let me know:

     

     

    using System;
    using System.Security.Cryptography;
    using System.Security.Cryptography.Pkcs;
    using System.Security.Cryptography.X509Certificates;
    
    namespace TestSHA256Signature
    {
     class Program
     {
      static void Main(string[] args)
      {
       byte[] data = { 1, 2, 3, 4, 5 };
       byte[] signed = null;
    
       signed = SignBuffer(data);
    
       bool valid = Verify(data, signed);
      }
    
      static byte[] SignBuffer(byte[] data)
      {
       byte[] signedData = null;
    
       try
       {
        X509Certificate2 cert = null;
        X509Store keyStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        try
        {
         keyStore.Open(OpenFlags.ReadOnly);
    
         X509Certificate2Collection certs = keyStore.Certificates.Find(X509FindType.FindByThumbprint, "babdf76c001a76256d8ed9a96e4cead0c6a9e2c8", false);
         if (certs != null && certs.Count > 0)
          cert = certs[0];
        }
        finally
        {
         keyStore.Close();
        }
    
        CmsSigner cmsSigner = new CmsSigner(cert);
        cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;
        cmsSigner.DigestAlgorithm = new Oid("SHA256");
        SignedCms signedCms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber, new ContentInfo(data), true);
        signedCms.ComputeSignature(cmsSigner, false);
        signedData = signedCms.Encode();
       }
       catch (CryptographicException e)
       {
        Console.WriteLine("Signing failed: " + e.ToString());
       }
       return signedData;
      }
    
      static bool Verify(byte[] data, byte[] signedData)
      {
       try
       {
        SignedCms signedCms = new SignedCms(new ContentInfo(data), true);
        signedCms.Decode(signedData);
        signedCms.CheckSignature(false); 
    
        return true;
       }
       catch (CryptographicException e)
       {
        Console.WriteLine("Verify failed: " + e.ToString());
       }
       return false;
      }
    
     }
    }
    

     


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"


    I tried the code above. this line :

     X509Certificate2Collection certs = keyStore.Certificates.Find(X509FindType.FindByThumbprint,"babdf76c001a76256d8ed9a96e4cead0c6a9e2c8", false);
    

    I had to replace it with

    X509Certificate2Collection certs = keyStore.Certificates.Find(X509FindType.FindByThumbprint, "BA319FAC0A05AAB0D7F4F1F7FC6F3D64E50683BD", false);
    


     because I have not the certificate babdf76c001a76256d8ed9a96e4cead0c6a9e2c8, I replaced it with my certificate BA319FAC0A05AAB0D7F4F1F7FC6F3D64E50683BD

    but at

    signedCms.ComputeSignature(cmsSigner, false);
    

    I get the same error "an internal error occurs". This is probability because your code is almost the same to my original code

    Many thank for uour support

    Wednesday, May 04, 2011 7:31 AM
  • Maybe I'm doing this wrong, but this is the code that I use for doing SHA2:

      public static byte[] ComputeHash(string data, string salt = "")
      {
       using (var provider = SHA512.Create())
       {
        var input = string.Format(CultureInfo.InvariantCulture, "{0}{1}",
         data, salt ?? string.Empty);
        var inputBytes = Encoding.Unicode.GetBytes(input);
        var hashBytes = provider.ComputeHash(inputBytes);
        return hashBytes;
       }
      }
    
    Evan


    Hi Evan,

    Your function is perfect to calculate an SHA256 hash on data.

    I need to sign data using an SHA256 hash algorithm and place the data and the digital sign in an PKCS envelope.

    Wednesday, May 04, 2011 7:39 AM
  • The error message “an internal error occurs” is not very informative or clear. What is the full exception message and the inner exception message?
    In the code below the CATCH section prints the exception and the inner exception message.

    What kind of certificate are you using? Does it have a private key?

    static byte[] SignBuffer(byte[] data)
        {
          byte[] signedData = null;
    
          try
          {
            X509Certificate2 cert = null;
            X509Store keyStore = new X509Store(StoreName.My, StoreLocation.CurrentUser);
            try
            {
              keyStore.Open(OpenFlags.ReadOnly);
    
              // This is an example where "babdf76c001a76256d8ed9a96e4cead0c6a9e2c8” is the thumb print of my certificate. You have to provide your certificate thumbprint. 
              X509Certificate2Collection certs = keyStore.Certificates.Find(X509FindType.FindByThumbprint, "babdf76c001a76256d8ed9a96e4cead0c6a9e2c8", false);
              if (certs != null && certs.Count > 0)
                cert = certs[0];
            }
            finally
            {
              keyStore.Close();
            }
    
            CmsSigner cmsSigner = new CmsSigner(cert);
            cmsSigner.IncludeOption = X509IncludeOption.EndCertOnly;
            cmsSigner.DigestAlgorithm = new Oid("SHA256");
            SignedCms signedCms = new SignedCms(SubjectIdentifierType.IssuerAndSerialNumber, new ContentInfo(data), true);
            signedCms.ComputeSignature(cmsSigner, false);
            signedData = signedCms.Encode();
          }
          catch (CryptographicException e)
          {
            Console.WriteLine("Signing failed: " + e.ToString());
            Console.WriteLine("Inner Exception: " + e.InnerException.ToString());
          }
          return signedData;
        }
    

     


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"
    Tuesday, May 10, 2011 3:11 PM
    Owner
  • I did not specified other details because I specified them in the first post.
    InnerException is null and no message in eventviewer. No other details in the exception.
    Please let me riassume :

    • In the first post, I asked for help in creating a signedcms, signing the document with a SHA256 hash algorithm.
    • I use a USB smart card and the CSP provided with the device is installed and works right.
    • The certificate support SHA256 and has the private Key and with third-party applications It works right.
    • You said that, with third-party CSP, signedCMS does not support SHA256
      ("An internal error occurred" when using SHA-2 algorithms with SignedCMS
      http://blogs.msdn.com/b/alejacma/archive/2010/06/02/quot-an-internal-error-ocurred-quot-when-using-sha-2-algorithms-with-signedcms.aspx)
      but it is possible only sign(not put in a PKCS envelope) a buffer using RSACryptoServiceProvider
    • I tried this solution and I get the buffer correctly signed but now I have to put it in a PKCS # 7 envelope.
    • Since I can not use signedCMS, can I create a PKCS envelope "manually" and enter the buffer I signed with RSACryptoServiceProvider()?
      or
      Can you recommend another way to get the PKCS7 envelope with the signature performed using RSACryptoServiceProvider?

    Many thanks

     

     


    Wednesday, May 11, 2011 8:25 AM
  • I have exactly the same problem...I haven't find any solution for now. Please keep in touch if you found something.

     

    Thanks

    Friday, May 13, 2011 11:18 AM
  • Me too.

    I need to create a detached Pkcs 7 Signature using SHA256.

    Is it possible to custom create a PKCS7 envelope (p7s) and embed it in the pdf file?
    Monday, May 16, 2011 10:10 AM
  • Me too.

    I need to create a detached Pkcs 7 Signature using SHA256.

    Is it possible to custom create a PKCS7 envelope (p7s) and embed it in the pdf file?

    happy if this topic is resolved and  other persons will benefit from it (of course) but please keep your posts in topic.
    Monday, May 16, 2011 10:45 AM
  • You may be able to use CryptMsg API to do what you need with SHA256.

    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"
    Wednesday, May 18, 2011 8:07 PM
    Owner
  • You may be able to use CryptMsg API to do what you need with SHA256.

    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"


    I tried the solution proposed and this is the situation I am now:
    on windows xp sp3 it works
    on windows 7 it does not work(with the same error)

    as you wrote, the problem now appears that the CSP provied by manufacturer of the smart card is not CNG. Can you confirm this? If so, is there a way to check if a CSP is CNG?

    Meanwhile, I reported the situation to the producer of smart cards and are awaiting their response about the support of CNG by their CSP

    Many thanks

    Monday, May 23, 2011 8:53 AM
  • You said "on windows 7 it does not work(with the same error) ". You're using the code from http://blogs.msdn.com/b/alejacma/archive/2010/04/09/how-to-call-cryptmsg-api-in-streaming-mode-c.aspx that uses CryptMsg API.

    When you say it fails with the same error do you mean that CryptMsgUpdate() API failed? What is the return code? If this function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. Can you please specify with detailed information what fails in your code when using the Smart Card CSP on Windows 7?


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"
    Monday, May 23, 2011 3:51 PM
    Owner
  • On Windows 7 x32

    Internal Error

    CryptMsgOpenToEncode error #-2146893792

     

    Tuesday, May 24, 2011 8:34 AM
  • You said "on windows 7 it does not work(with the same error) ". You're using the code from http://blogs.msdn.com/b/alejacma/archive/2010/04/09/how-to-call-cryptmsg-api-in-streaming-mode-c.aspx that uses CryptMsg API.

    When you say it fails with the same error do you mean that CryptMsgUpdate() API failed? What is the return code? If this function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. Can you please specify with detailed information what fails in your code when using the Smart Card CSP on Windows 7?

     
    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"

    Yes, I use that code.
    Unfortunately, today and tomorrow I will not be in office so I can not confirm with certainty the details of the error, I can do it on Thursday 26

    Wath I remember is that the error was on CryptMsgOpenToEncode(I have with me the code but not the smart card
    ) and the message was internal error on win7 64 bits.

    however, the post of pinokar seems confirm these details.

    if there will not be more news, I will communicate my exact details on Thursday.

    Many thanks

     


    • Edited by nmontero Tuesday, May 24, 2011 1:11 PM
    Tuesday, May 24, 2011 9:45 AM
  •  

    this function

    hMsg = Win32.CryptMsgOpenToEncode(
                        Win32.X509_ASN_ENCODING | Win32.PKCS_7_ASN_ENCODING,
                        0,
                        Win32.CMSG_SIGNED,
                        ref SignedInfo,
                        null,
                        ref StreamInfo
                    );

     

    return an IntPtr.Zero and the GetLastWin32Error is  -2146893792

    Tuesday, May 24, 2011 10:54 AM
  • You said "on windows 7 it does not work(with the same error) ". You're using the code from http://blogs.msdn.com/b/alejacma/archive/2010/04/09/how-to-call-cryptmsg-api-in-streaming-mode-c.aspx that uses CryptMsg API.
    When you say it fails with the same error do you mean that CryptMsgUpdate() API failed? What is the return code? If this function fails, GetLastError may return an Abstract Syntax Notation One (ASN.1) encoding/decoding error. Can you please specify with detailed information what fails in your code when using the Smart Card CSP on Windows 7?

    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"
    this are my details :
    hMsg = Win32.CryptMsgOpenToEncode(
              Win32.X509_ASN_ENCODING | Win32.PKCS_7_ASN_ENCODING,
              0,
              Win32.CMSG_SIGNED,
              ref SignedInfo,
              null,
              ref StreamInfo
            );
    
    hMsg is equals to IntPtr.Zero so the code throws this exception :
    if (hMsg.Equals(IntPtr.Zero))
            {
              throw new Exception("CryptMsgOpenToEncode error #" + Marshal.GetLastWin32Error().ToString(), new Win32Exception(Marshal.GetLastWin32Error()));
            }
    

    where

    Marshal.GetLastWin32Error().ToString() returns  "-2146893792"

    and new Win32Exception(Marshal.GetLastWin32Error()).Message is "an internal error occurs"

    working with VS2010 on win 7 professional x64

     

    Thursday, May 26, 2011 9:37 AM
  • At this point we would need to collect and analyze an iDNA trace to help identify why CryptMsgOpenToDecode() fails with an internal error. This is beyond what we can cover here in this forums case and as such your question falls into the paid support category which requires a more in-depth level of support.  Please visit this link to see the various paid support options that are available to better meet your needs:  http://support.microsoft.com/default.aspx?id=fh;en-us;offerprophone. If this turns out to be a bug, there will be no charge for the support. Please be sure to reference this thread and this case number when opening your case: 111042163429532.


    --Trevor H.
    Send files to Hotmail.com: "MS_TREVORH"
    Monday, June 06, 2011 4:02 PM
    Owner
  • Hello, my solution for WIN 7 32 Bit, and reason why i believe this bug is in windows is described here:

    http://social.msdn.microsoft.com/Forums/en-US/netfxbcl/thread/217776fa-5dcd-41a6-a800-b401509fbbf0

    There are defined wrong constants in CAPIBase:

            internal const string szOID_OIWSEC_SHA256 = "2.16.840.1.101.3.4.1";
            internal const string szOID_OIWSEC_SHA384 = "2.16.840.1.101.3.4.2";
            internal const string szOID_OIWSEC_SHA512 = "2.16.840.1.101.3.4.3";

    the solution in my project is here:

    (It is mostly taken from here: https://clrsecurity.svn.codeplex.com/svn/Security.Cryptography/src/Oid2.cs
    https://clrsecurity.svn.codeplex.com/svn/Security.Cryptography/src/CapiNative.cs)

    Full source of my project is here: http://fastzep.scholtz.sk/FastZep3-source.zip

    [SecurityCritical]
            [PermissionSet(SecurityAction.LinkDemand, Unrestricted = true)]
            public static void RegisterSha2OidInformationForRsa()
            {
                // On Windows 2003, the default ALGID -> OID mapping for the SHA2 comes back with an unknown
                // ALG_ID of 0.  The v2.0 CLR however expects unknown ALG_IDs to be mapped to -1, and therefore
                // fails to map this unknown value to the correct SHA-256 ALG_ID.  If we're on Windows 2003 and
                // CLR 2.0, we'll re-register the SHA-256 OID so that the CLR can pick it up.
                if (true || (Environment.OSVersion.Platform == PlatformID.Win32NT &&
                    Environment.OSVersion.Version.Major == 5 &&
                    Environment.OSVersion.Version.Minor == 2 &&
                    Environment.Version.Major == 2))
                {
                    Oid2[] sha2Oids = new Oid2[]
                    {
                        new Oid2(CapiNative.WellKnownOids.Sha256, "sha256", OidGroup.HashAlgorithm, (int)CapiNative.AlgorithmID.Sha256, CngAlgorithm.Sha256, null),
                        //new Oid2(CapiNative.WellKnownOids.Sha384, "sha384", OidGroup.HashAlgorithm, (int)CapiNative.AlgorithmID.Sha384, CngAlgorithm.Sha384, null),
                        //new Oid2(CapiNative.WellKnownOids.Sha512, "sha512", OidGroup.HashAlgorithm, (int)CapiNative.AlgorithmID.Sha512, CngAlgorithm.Sha512, null)
                    };
    
                    foreach (Oid2 sha2Oid in sha2Oids)
                    {
                        // If the OID is currently registered to an ALG_ID other than 0, we don't want to break
                        // that registration (or duplicate it) by overwriting our own.
                        Oid2 currentOid = Oid2.FindByValue(sha2Oid.Value, sha2Oid.Group, false);
    
                        if (currentOid == null || !currentOid.HasAlgorithmId || currentOid.AlgorithmId == 0)
                        {
                            // There is either no current OID registration for the algorithm, or it contains a
                            // CAPI algorithm mapping which will not be understood by the v2.0 CLR.  Register a
                            // new mapping which will have the CAPI algorithm ID in it.
                            sha2Oid.Register(OidRegistrationOptions.InstallBeforeDefaultEntries);
                            currentOid = Oid2.FindByValue(sha2Oid.Value, sha2Oid.Group, false);
                            if (currentOid == null || !currentOid.HasAlgorithmId || currentOid.AlgorithmId == 0)
                            {
                                throw new Exception("Váš systém nepodporuje SHA2 algoritmy pre podpis!");
                            }
                        }
                    }
                }
            }
    My project is open source software for qualified electronic signiture in slovakia, but it is quite annoying that this bug in windows is there for several years and nothing is improving. My software technically works only on WIN 7 32 Bit, but recently i had a call from one guy that has successfully used it on win 7 64 bit. I dont know how was that possible and i will probably take a deeper look on it.
    Thursday, August 02, 2012 2:16 PM