C # эквивалент подписи OpenSSL - PullRequest
0 голосов
/ 28 ноября 2018

Я должен подписать некоторые данные с помощью SHA256, и у меня есть пример, созданный с помощью OpenSSL:

johnd@johns-machine:~/sandboxcerts$ signingString="(request-target): post /oauth2/token
date: Wed, 11 Apr 2018 15:07:23 GMT
digest: SHA-256=47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU=
x-ing-reqid: e86bf09b-d772-4528-af83-ba42aa594ac4"

johnd@johns-machine:~/sandboxcerts$ signature=`printf "$signingString" | openssl dgst -sha256 -sign ~/sandboxcerts/example_client_signing.key -passin "pass:changeit" | openssl base64 -A`

Я пытаюсь сделать то же самое в C #, например:

// loading my private key
X509Certificate2 cert = new X509Certificate2(certPath, certPass);
RSACryptoServiceProvider key = cert.PrivateKey as RSACryptoServiceProvider;

string signingString = @"(request-target): post /oauth2/token
date: Wed, 11 Apr 2018 15:07:23 GMT
digest: SHA - 256 = 47DEQpj8HBSa +/ TImW + 5JCeuQeRkm5NMpJWZG3hSuFU =
        x - ing - reqid: e86bf09b - d772 - 4528 - af83 - ba42aa594ac4";

signingString = signingString.Replace("\n", string.Empty);
signingString = signingString.Replace("\r", string.Empty);
signingString = signingString.Replace("\t", string.Empty);

byte[] sig = privKey.SignData(Encoding.ASCII.GetBytes(signingString), CryptoConfig.MapNameToOID("SHA256"));
Console.WriteLine(Convert.ToBase64String(sig));

но я не получаю тот же результат.Я пробовал разные кодировки и удалял или не удалял новые строки, вкладки и т. Д., Но все равно не понял правильно.

1 Ответ

0 голосов
/ 29 ноября 2018

Убедитесь, что в обоих случаях используется одна и та же схема подписи.SHA256 не является схемой подписи.Это просто алгоритм создания вашего дайджеста для подписи.На основе OpenSSL CLI wiki (https://wiki.openssl.org/index.php/Command_Line_Utilities)) алгоритм подписи определяется типом ключа подписи (RSA, DSA и т. Д.). Если вы используете ключ RSA, по умолчанию используется схема pkcs # 1 v1.5.

Я не эксперт по C #, поэтому могут быть более эффективные способы подписывания PKCS # 1 v1.5, но я обнаружил RSAPKCS1SignatureFormatter после быстрого поиска в Google (https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rsapkcs1signatureformatter?view=netframework-4.7.2). Этот класскажется, работает вместе с RSACryptoServiceProvider , который вы уже используете.

Пример от Microsoft:

using System;
using System.Security.Cryptography;

class RSASample
{

    static void Main()
    {
        try
        {
            //Create a new instance of RSACryptoServiceProvider.
            using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
            {
                //The hash to sign.
                byte[] hash;
                using (SHA256 sha256 = SHA256.Create())
                {
                    byte[] data = new byte[] { 59, 4, 248, 102, 77, 97, 142, 201, 210, 12, 224, 93, 25, 41, 100, 197, 213, 134, 130, 135 };
                    hash = sha256.ComputeHash(data);
                }

                //Create an RSASignatureFormatter object and pass it the 
                //RSACryptoServiceProvider to transfer the key information.
                RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(rsa);

                //Set the hash algorithm to SHA256.
                RSAFormatter.SetHashAlgorithm("SHA256");

                //Create a signature for HashValue and return it.
                byte[] SignedHash = RSAFormatter.CreateSignature(hash);
            }

        }
        catch (CryptographicException e)
        {
            Console.WriteLine(e.Message);
        }
    }

}

РЕДАКТИРОВАТЬ: После дальнейшей проверкиВ C # документах вы можете попытаться внести незначительные изменения в ваш текущий фрагмент кода. Третий параметр для SignData() - это RSASignaturePadding, и вы можете попытаться указать для него RSASignaturePadding.Pkcs1 (https://docs.microsoft.com/en-us/dotnet/api/system.security.cryptography.rsasignaturepadding?view=netframework-4.7.2)

В основном ваша вторая последняя строка кода будет выглядеть так:

byte[] sig = privKey.SignData(Encoding.ASCII.GetBytes(signingString), CryptoConfig.MapNameToOID("SHA256"), RSASignaturePadding.Pkcs1);
...