Кодирование RSA с помощью Crypto++ и декодирование с помощью C# RSACryptoServiceProvider
Доброе утро,
У меня есть клиент-серверное приложение, общающееся через сокеты UDP. Я хочу закодировать связь с RSA (кодировать ключи) и AES для кодирования дейтаграммы.
На стороне клиента находится в C++ и на стороне сервера в C#
Я сейчас пытаюсь закодировать AES IV ключом с RSA, но я получаю ошибку при декодировании в C#:
Тип исключения: System.Security.Cryptography.CryptographicException
Сообщение об исключении: Cryptography_OAEPDecoding
Вот мой код кодирования (на стороне клиента, C++)[EDIT] изменил RSAES_PKCS1v15_Encryptor на RSAES_OAEP_SHA_Encryptor
const CryptoPP::Integer n("107289343054719278577597018805838066296333011963085747309982087864392842699433873606133118875978275304651444098131280023618603357722259282514858925191134541966986361546234507079678544203468616135436686852577772762581654429498496768721214543879181421353486700409082948114039206485653595743465270256058198245113.");
const CryptoPP::Integer e("17.");
[...]
void Crypto::CryptRSA(const std::string & bufferIn, std::string & bufferOut, const CryptoPP::Integer &n, const CryptoPP::Integer &e)
{
CryptoPP::AutoSeededRandomPool rnd;
CryptoPP::RSA::PublicKey pubKey;
pubKey.Initialize(n, e);
CryptoPP::RSAES_OAEP_SHA_Encryptor encryptor(pubKey);
size_t ecl = encryptor.CiphertextLength(bufferIn.size());
CryptoPP::SecByteBlock ciphertext(ecl);
encryptor.Encrypt(rnd, (CryptoPP::byte*)bufferIn.c_str(), bufferIn.size(), ciphertext);
bufferOut = std::string((char*)ciphertext.data(), ecl);
}
А вот мой код декодирования (на стороне сервера. C#)
private static string _keyN = "107289343054719278577597018805838066296333011963085747309982087864392842699433873606133118875978275304651444098131280023618603357722259282514858925191134541966986361546234507079678544203468616135436686852577772762581654429498496768721214543879181421353486700409082948114039206485653595743465270256058198245113";
private static string _keyE = "17";
private static string _keyD = "50489102613985542860045655908629678257097887982628586969403335465596631858557116991121467706342717790424208987355896481702872168339886721183463023619357421741798172532326737925480536247565713413538718832057918801452980775480097195493999319542331774866185094818177243836015292183598722700529776296282728256145";
[...]
public static byte[] DecryptRSA(byte[] encrypted)
{
BigInteger n, e, d;
BigInteger.TryParse(_keyN, out n);
BigInteger.TryParse(_keyE, out e);
BigInteger.TryParse(_keyD, out d);
CspParameters csp = new CspParameters();
csp.KeyContainerName = "RSA Test (OK to Delete)";
csp.ProviderType = 1;
csp.KeyNumber = 1;
var rsa = new RSACryptoServiceProvider(csp);
rsa.PersistKeyInCsp = false;
var param = new RSAParameters()
{
Modulus = n.ToByteArray().Skip(1).ToArray(),
Exponent = e.ToByteArray().Skip(1).ToArray(),
D = d.ToByteArray().Skip(1).ToArray(),
};
rsa.ImportParameters(param);
return rsa.Decrypt(encrypted.ToArray(), true);
}
Итак, мне интересно, что я сделал не так в моем коде.
В C++ я могу кодировать и декодировать мои дейтаграммы, но когда я пытаюсь декодировать с помощью C#, это не работает.
Спасибо и извините за мой плохой английский.
1 ответ
BigInteger.ToByteArray возвращает значение в порядке байтов.
В то время как RSAParameters
поля действительно с прямым порядком байтов (как объяснено здесь).
Вы можете попробовать что-то вроде:
Modulus = n.ToByteArray().Reverse().ToArray()