2

I've been since yesterday trying a lot of the "solutions" on StackOverflow, but none seems to work. Given a .pfx certificate with a private key I need to sign a byte array (firmware version of the tracking unit we use). Here are the things I've tried:

private byte[] generateSignature(byte[] data, X509Certificate2 certificate)
    {
        RSACryptoServiceProvider key = new RSACryptoServiceProvider();
        key.FromXmlString(certificate.PrivateKey.ToXmlString(true));

        return key.SignData(data, CryptoConfig.MapNameToOID("SHA256"));
}

And also:

private byte[] generateSignature(byte[] data, X509Certificate2 certificate)
    {
        string alg = CryptoConfig.MapNameToOID("SHA256");

        RSACryptoServiceProvider rsaProvider = (RSACryptoServiceProvider)certificate.PrivateKey;

        return rsaProvider.SignData(orig, alg);
}

And also:

private byte[] generateSignature(byte[] data, X509Certificate2 certificate)
{
    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
    {
            byte[] hash;
            using (SHA256 sha256 = SHA256.Create())
            {
                hash = sha256.ComputeHash(data);
            }

            RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(rsa);


            RSAFormatter.SetKey(certificate.PrivateKey);

            RSAFormatter.SetHashAlgorithm("SHA256");


            return RSAFormatter.CreateSignature(hash);
}

And finally:

private byte[] generateSignature(byte[] data, X509Certificate2 certificate)
{
        RSACryptoServiceProvider csp = (RSACryptoServiceProvider)certificate.PrivateKey;
        SHA1Managed sha1 = new SHA1Managed();
        SHA256Managed sha256 = new SHA256Managed();

        byte[] hash = sha256.ComputeHash(data);

        csp.SignHash(hash, CryptoConfig.MapNameToOID("SHA256"));
}

On all of these I get the error:

System.Security.Cryptography.CryptographicException: 'Invalid algorithm specified.'

I know my key is 256hash compatible because I've used the command:

openssl x509 -in C:\cert.pfx -text -noout

And the Signature Algorithm was sha256WithRSAEncryption.

  • 2
    Did you look in this question https://stackoverflow.com/questions/7444586/how-can-i-sign-a-file-using-rsa-and-sha256-with-net ? – Alexander Goldabin Jan 17 '20 at 11:35
  • 1
    @AlexanderGoldabin Yes, it also didn't work. But the error I get in that case is "Key not valid for use in specific state" which I think it means it has to be an exportable key, but on our store the keys have to be set to non-exportable – Dário Hermann Jan 17 '20 at 11:40
  • 3
    You should use GetRSAPrivateKey(), not the PrivateKey property, and use the newer SignData/SignHash overloads. (An answer already present in the linked question, but towards the bottom, because it’s new). – bartonjs Jan 17 '20 at 17:11
  • 1
    @bartonjs I didn't know that method existed, the problem is, I'm using .NET 4.5.2, and that method only works with >= 4.6 – Dário Hermann Jan 20 '20 at 12:47
  • 1
    I'd strongly encourage you to take a newer dependency. All Windows 10 machines have 4.6 or newer. Most Windows 10 machines have 4.7.2 or newer. 4.7.2 is the first version to fully support .NET Standard 2.0. .NET Cryptography has gotten a lot of enhancements in 4.6+ (this being one of the most visible ones). – bartonjs Jan 20 '20 at 15:20
  • 1
    @bartonjs Thank you so very very much! It worked like a charm! – Dário Hermann Jan 21 '20 at 14:12

0 Answers0