Подтвердить что ты не робот

Почему я получаю исключение "Недопустимый алгоритм"

Вот мой код.

X509Certificate pXCert = new X509Certificate2(@"keyStore.p12", "password");
RSACryptoServiceProvider csp = (RSACryptoServiceProvider)pXCert.PrivateKey;
string id = CryptoConfig.MapNameToOID("SHA256");
return csp.SignData(File.ReadAllBytes(filePath), id);

В последней строке я получаю исключение:

System.Security.Cryptography.CryptographicException "Указан неверный алгоритм".

Что я делаю неправильно?

UPDATE:

id = 2.16.840.1.101.3.4.2.1

4b9b3361

Ответ 1

Нет проблем с кодом .NET или кодом CSP, который вы предоставили.

Ваша проблема в том, что CSP просто не поддерживает SHA 256. Вы можете получить дополнительную информацию здесь

Ответ 2

Обратите внимание, что я использую SHA512, но SHA256 будет работать с приведенными ниже примерами:

"Указан неверный алгоритм" У меня ушло навсегда разобраться, и я попробовал практически все. Рекомендую Гонсало Галлотти за размещение ссылки на фрагмент кода, который мне помог. Я прокомментировал свой код, чтобы показать, что делает каждый шаг. ПРИМЕЧАНИЕ: этот код не будет работать без правильно сгенерированного сертификата, который размещен под примером кода:

public void GetCertificate() {

    // Get the Machine Cert Store
    var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

    string alg = CryptoConfig.MapNameToOID("SHA512");

    // Open the cert store
    store.Open(OpenFlags.ReadWrite);

    // Loop through each certificate within the store
    foreach (X509Certificate2 myCert in store.Certificates)
    {
        // Get the certificate we are looking for
        if (myCert.IssuerName.Name.Contains("CN=YourSite"))
        {
            // Check if the certificate has a private key
            if (myCert.HasPrivateKey)
            {
                // Get your custom signature as a string
                string mySignature = GetSignatureString();

                // Convert signature to byte array
                byte[] originalData = Encoding.UTF8.GetBytes(mySignature);

                // Create RSA provider from private key
                RSACryptoServiceProvider rsaProvider = (RSACryptoServiceProvider)myCert.PrivateKey;

                // Sign the signature with SHA512
                byte[] signedSignature = signedSignature = rsaProvider.SignData(originalData, alg);

                if (rsaProvider.VerifyData(originalData, alg, signedSignature))
                {
                    // Signature is verified Do Stuff
                }
                else
                {
                    throw new Exception("The data does not match the signature.");
                }
            }
        }
    }
}

Далее - сертификат должен быть SHA512 и использовать CSP (провайдер криптографических услуг), который поддерживает SHA512. Вот список CSP и их возможностей. Если вы ищете SHA512, вы найдете "Microsoft Enhanced RSA и AES Cryptographic Provider". По умолчанию генерирующие сертификаты не используют это (по крайней мере, в Windows), поэтому вы должны указать его при создании сертификата.

Создать закрытый ключ и сертификат - на этом этапе вам будут заданы вопросы о штате, регионе и т.д.

openssl req -x509 -nodes -sha512 -newkey rsa:2048 -keyout 512key.pem -out 512cert.pem -days 3650

Создайте файл PFX для импорта в хранилище сертификатов с помощью Microsoft Enhanced RSA и AES Cryptographic Provider:

openssl pkcs12 –export –in 512cert.pem –inkey 512key.pem –CSP "Microsoft Enhanced RSA and AES Cryptographic Provider" –out 512pfx.pfx

Ответ 3

Имея аналогичную проблему, но только разрешил ее. Если вы не используете X509, а просто простой RSACryptoServiceProvider для получения ключей, то поддерживается только SHA1.

Ответ 4

Для dot net framework 4.7.0 или выше не принимает sha1, так что настройте ниже в запуске приложения. это работало хорошо для меня. AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true); AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);

Ответ 5

Возможно, вы пришли сюда во время переноса приложения из .NET Framework 4.7 и более ранних версий в 4.7.1 или более поздние версии.
Если вы получаете исключение System.Security.Cryptography.CryptographicException: Invalid algorithm specified., причина в том, что алгоритмы по умолчанию SignedXML и SignedXMS были изменены на SHA256 для приложений, предназначенных для .NET Framework 4.7.1 и более поздних версий (из руководства по миграции Microsoft.NET)

В этом руководстве вы также найдете решение:

Для приложений, нацеленных на .NET Framework 4.7.1 и более поздние версии, если использование SHA256 нежелательно, вы можете восстановить значение по умолчанию для SHA1, добавив следующий переключатель конфигурации в раздел времени выполнения вашего файла конфигурации приложения:

<AppContextSwitchOverrides value="Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms=true;  
                  Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms=true" />

Но это может не всегда работать, особенно для веб-приложений, как вы можете прочитать в этом блоге, к счастью, вместе с ответом. Нужно только добавить несколько строк в Application_Start

protected void Application_Start(object sender, EventArgs e)
{
   [...]
   AppContext.SetSwitch("Switch.System.Security.Cryptography.Xml.UseInsecureHashAlgorithms", true);
   AppContext.SetSwitch("Switch.System.Security.Cryptography.Pkcs.UseInsecureHashAlgorithms", true);
}