Преобразование сигнатуры байтового массива алгоритма RSA в строку и обратно в байтовый массив снова в .NET C #

Я разрабатываю проект .NET. Я занимаюсь шифрованием некоторых конфиденциальных данных. Я использую для этого алгоритм RSA. Я могу успешно проверить хеш-сообщение, используя закрытый ключ, открытый ключ и подпись.

Но у меня возникла проблема с преобразованием подписи байтового массива, сгенерированной алгоритмом RSA, в строку и преобразованием этой строки обратно в байтовый массив для проверки. Но проверка не выполняется, если я проверяю подпись с помощью массива байтов, который конвертируется обратно из строки подписи. Мой сценарий ниже.

Это мой полный класс криптографии с алгоритмом RSA.

public class Cryptograph:ICryptograph
    {
        private string RsaHashAlgorithm { get; set; }

        public Cryptograph()
        {
            this.RsaHashAlgorithm = "SHA256";
        }

        public RSAParameters[] GenarateRSAKeyPairs()
        {
            using (var rsa = new RSACryptoServiceProvider(2048))
            {
                rsa.PersistKeyInCsp = false;
                RSAParameters publicKey = rsa.ExportParameters(false);
                RSAParameters privateKey = rsa.ExportParameters(true);
                return new RSAParameters[]{ privateKey , publicKey };
            }
        }

        public byte[] SignRsaHashData(RSAParameters privateKey,byte[]hashOfDataToSign)
        {
            using (var rsa = new RSACryptoServiceProvider(2048))
            {
                rsa.PersistKeyInCsp = false;
                rsa.ImportParameters(privateKey);

                var rsaFormatter = new RSAPKCS1SignatureFormatter(rsa);
                rsaFormatter.SetHashAlgorithm(RsaHashAlgorithm);

                return rsaFormatter.CreateSignature(hashOfDataToSign);
            }
        }

        public bool VerifyRsaSignature(RSAParameters publicKey,byte[]hashOfDataToSign, byte[] signature)
        {
            using (var rsa = new RSACryptoServiceProvider(2048))
            {
                rsa.ImportParameters(publicKey);

                var rsaDeformatter = new RSAPKCS1SignatureDeformatter(rsa);
                rsaDeformatter.SetHashAlgorithm(RsaHashAlgorithm);

                return rsaDeformatter.VerifySignature(hashOfDataToSign, signature);
            }
        }

    }

Тестирую проверку. Ниже рабочий код и успешно проверенный

[TestMethod]
        public void VerifyRsaEncryptionSign()
        {
            var document = Encoding.UTF8.GetBytes("test message");
            byte[] hashedDocument;
            using (var sha256 = SHA256.Create())
            {
                hashedDocument = sha256.ComputeHash(document);
            }

            Cryptograph crypto = new Cryptograph();
            RSAParameters[] keys = crypto.GenarateRSAKeyPairs();
            RSAParameters privateKey = keys[0];
            RSAParameters publicKey = keys[1];

            byte[] signature = crypto.SignRsaHashData(privateKey, hashedDocument);       
            bool verified = crypto.VerifyRsaSignature(publicKey, hashedDocument, signature);
            Assert.IsTrue(verified);
        }

Выше кода модульный тест пройден и успешно проверен.

Но я хочу преобразовать массив байтов подписи и преобразовать эту строку в массив байтов обратно для проверки, как показано ниже.

[TestMethod]
        public void VerifyRsaEncryptionSign()
        {
            var document = Encoding.UTF8.GetBytes("test message");
            byte[] hashedDocument;
            using (var sha256 = SHA256.Create())
            {
                hashedDocument = sha256.ComputeHash(document);
            }

            Cryptograph crypto = new Cryptograph();
            RSAParameters[] keys = crypto.GenarateRSAKeyPairs();
            RSAParameters privateKey = keys[0];
            RSAParameters publicKey = keys[1];

            byte[] signature = crypto.SignRsaHashData(privateKey, hashedDocument);
            string stringSignature = Encoding.UTF8.GetString(signature);// Converted byte array to string
            signature = Encoding.UTF8.GetBytes(stringSignature);//convert string back to byte array
            bool verified = crypto.VerifyRsaSignature(publicKey, hashedDocument, signature);
            Assert.IsTrue(verified);
        }

Когда я запускаю модульный тест, проверка не выполняется. Что не так с моим кодом? Как мне его успешно преобразовать? Я бы тоже хотел задать дополнительный вопрос. Можно ли преобразовать хешированное сообщение обратно в исходную строку?


person Wai Yan Hein    schedule 11.07.2016    source источник


Ответы (1)


Используйте базу 64. Подписи состоят из случайных байтов; однако не все случайные байты представляют собой допустимый символ при декодировании.

В основном вам следует декодировать только те строки, которые ранее были закодированы.

person Maarten Bodewes    schedule 11.07.2016
comment
Можно ли с помощью моего кода преобразовать хешированное сообщение обратно в исходную строку? - person Wai Yan Hein; 11.07.2016
comment
Извините, я не понимаю, что вы пытаетесь сделать. Пожалуйста, будьте как можно точнее. - person Maarten Bodewes; 11.07.2016
comment
Теперь я хеширую сообщение. Затем подпишите сообщение, используя закрытый ключ. Затем я просто проверяю, используя знак и открытый ключ. Но как я могу снова расшифровать хешированное значение, чтобы получить исходное сообщение? На самом деле то, что я делаю со своим приложением, - это шифрование сообщения закрытым ключом. Затем получатель расшифрует сообщение с помощью открытого ключа. Подпись также будет отправлена. Как мне этого добиться? - person Wai Yan Hein; 11.07.2016
comment
Вы не можете, хэши - это один из способов. Шифрование должно выполняться с использованием открытого ключа получателя. Если вам требуется меньше места для подписи, используйте ECDSA. - person Maarten Bodewes; 11.07.2016
comment
Большое спасибо за поддержку. - person Wai Yan Hein; 11.07.2016