C# 默认使用的 RSA 算法是什么,它在 Crypto++ 中的合适参数是什么?

What is the RSA Algorithm used by C# by default, and what is it's appropriate parameter in Crypto++?

我正在研究加密,在这个过程中,我偶然发现了这个 C# 代码..

//Encrypts a string with RSA public key
public static string EncryptTextRSA(string text, int keySize, string publicKeyXml)
{
    var encrypted = RSAEncrypt(Encoding.UTF8.GetBytes(text), keySize, publicKeyXml);
    return Convert.ToBase64String(encrypted);
}

//Rsa encryption algorithm
public static byte[] RSAEncrypt(byte[] data, int keySize, string publicKeyXml)
{
    using (var provider = new RSACryptoServiceProvider(keySize))
    {
        provider.FromXmlString(publicKeyXml);
        return provider.Encrypt(data, OAEP);
    }
}

(来自 PHP 后端)的信息最终是这样的:

私钥:

<RSAKeyValue>
   <Modulus>3+A8GT1MAdf+MzIZGbGa5GSAjtvxsIeJnsZKeIP6oiK76TiTQqr6vgYKpE+jQBdI6WMsWv2H9TYWv6NmfzMI9+RHV82V5r71vG5o0GwvfzHj3I/FzYwvM8vjXiHIO1T4kD4ky4VNTtq29sW82pJeo4N50EgiWNvnczYKoG8PUaQIoW7j7kuDhgLtWx40zTwR6kxiqJm80oJRyLgxZEkH9YSK/rsGGtKmkOSXpMIAaJoDtBExqYtiBD6v4juAHejdqgUa1xuWLvgvdJhjGEP0kU1C2sye1QYUXN2el2+XU/N3qhsS2g4wn4VBWYNOm2Heq/rDUmkPLRcrRXzYTlVmXQ==</Modulus>
   <Exponent>AQAB</Exponent>
   <P>8Iu+4wMdHYmpzOvujzsnOCjQxRKPZxFnw9qDG1xf2/h727kfDyr2FBCXvGNHTLuRzwbc++/nUmdyvEh2uhAYlTU8eB/IcTiSzDeUWye/Bq6CL6bHR3f65bIK4K0aqFyq8eDtIEzaU0y1TxXnp6Sosk6sqp28keE1C2acnIaXQpM=</P>
   <Q>7kJRhudKzuo33N5hoTYz6rhvU++l5gdFP6RHRoGW6qBjVlxIzptUE+fYVZIvvyYQDewccKVEOb4s8etjL98lfJ85tHCxengDou9hsNh0FERM65QYN8iPXLAU39Ubca5mmkm7Hb3f3JebZAMfxe2Q2hqU9ZHFIhiiVqpmvrpqmU8=</Q>
   <DP>tfwj6L+8UVKLQlvk2jwYieZnPBG0qHeEl6pDsnmKlHND0ZIWq3UHQ1riUUaS9LybrZM1sO1phvB433W7TT1MO+ZQ31i8Xtw8Q4BxHx3M6hMwrzhwX+On0AuJKz4LgwDI28Id5GgAbTEFotWhszVh47Sd8V7xATTu2rdBGTLCUT0=</DP>
   <DQ>sQIiMZhKMpk9sWChpbRwM7ScOP61AMVsBBEXRuFl7qADzRg4mw45E6TOSxyVTmyHxuAgbOvLWR7Zo01eXiVpY0GkDFMg97yL7xPrPwhAjQIFJ4vZxi/BmnnSuExJ3FZWMdAPLNRwqSEVN+M+SrzpPbA79Ik8rM0iZkKonJBAO+8=</DQ>
   <InverseQ>DClm/3Fg7j45kjUB1Cb3XKT73j+RGHmOQUzVlNAlkCocjx4qVmOuIqi2eMKUbaTgsOPXyZQ82vQvYmQBmR4/b7gncK1X8mlcrVzVwEaO3kr7BOm8OsNnvD/V9rcwqiJCzoMFYZGod3tbJjvzg02xrBN9+nMLUkyZLmaUojAk1pY=</InverseQ>
   <D>TlfT8CkpLgP96sB/VCR4xa/95QBG5bWojS1q5h2ZWZ+6DnVD4zKeKF1I4BMWV9lOJI4V+Yl7SG4zK8Dsn1qmqsjxxmIlMOhmahhhCX6yaFp3GLofSDzkT8XrvQcpYMntady1V5tAYHXdTSIJYpuSDrp1qFN14Y6iwgiJU3dJ7xFGfbc0D6RXO3r0f/n4QIbIX2wzYc0H5AonKWvVEXY7dUZPhOca1+okEwnDtoIObCTuuuesieK3nv4ZwoJX4eDXD9bCv2jXlv5yIzjKLZvH69TN3QNH59gktRA4ZUkG9LhKhwESQ7NrxhcwKJSxPVkk4ECVcSNxINATgw94mW9AqQ==</D>
</RSAKeyValue>

以及生成的 C# 程序生成的密文:

Jmk6JpFNODhMf/8r6fa8kQfyTPiVhZg9oyyYBmh1WXJrn5D5juvzZ8xjYzFUPaGZy+wiSlSEkR69o6UcjOkSi3B3dmtmFktGb0D36/yYneNES0Agca+UHWPn8triIMw4EYDuo8auMQCGR3gGg/MiJrW+Bo2gvZCoLxkAdVgoSl1e20LB1TH6UtGOs0ioMyuwG8TJSYcJVbvZZI+aZDW2YR6nrrBqcWa6n/KlLXWfbDiRq1rkmQpiIwpDRbiHOB+rao2Q93g++MYHtM0IDGWfvnWXRgXYcptMVTvzhvcdzdFwL6taa5LDAhs2HzFEawpk7EM5MpBlg1bQjCeWImIlWw==

我一直在尝试在 Visual Studio 2014 年使用 Crypto++ 实现相同的功能,问题包括缺乏自动 XML 解析以及导入预生成模数和指数的一般能力.

我的 C++ 代码是这样的:

std::string base64ToHex(std::string base64String)
{
    std::string decodedString, finalString;
    CryptoPP::StringSource river(base64String, true,
        new CryptoPP::Base64Decoder(new CryptoPP::StringSink(decodedString)));

    CryptoPP::StringSource stream(decodedString, true,
        new CryptoPP::HexEncoder(new CryptoPP::StringSink(finalString)));

    finalString.erase(std::remove(finalString.begin(), finalString.end(), '\n'), finalString.end());

    return finalString;
}    

std::string RSAEncryptString(std::string message, std::string modulus, std::string exponent)
{
    char modulusCharred[1024];
    strncpy_s(modulusCharred, base64ToHex(modulus).c_str(), sizeof(modulusCharred));
    modulusCharred[sizeof(modulusCharred) - 1] = 0;

    char exponentCharred[1024];
    strncpy_s(exponentCharred, base64ToHex(exponent).c_str(), sizeof(exponentCharred));
    exponentCharred[sizeof(exponentCharred) - 1] = 0;

    Integer n(modulusCharred);
    Integer e(exponentCharred);

    RSA::PublicKey pubKey;
    pubKey.Initialize(n, e);

    Integer m, c; m = Integer((const byte *)message.data(), message.size()); c = pubKey.ApplyFunction(m);
    std::stringstream ssr; ssr << hex << c;

    return (ssr.str());
}

生成的密文(通过C++实现,使用不同的私钥):

hXM7DAe/5tymIzEsQgNGiiCnA1p/J1x7Tvu6Lhbv6ApkGwfXuDi4bXZhknLDmbTXkoMVrHKnHZE6X1+pAi9+4SxN2sVcZ/cEQx+6riBsYZrSOVqq9bzEOD8J85FIUIbWZmp8kiKBCzK7F9Ke+q5/x9aOHh29Bq7cFu//

尝试解密密文时(使用相应的私钥,它无法识别它,这与 C# 示例不同,它可以识别)

该代码基于 Crypto++ 的 RAW RSA Encryption Wiki,C# 中默认使用的算法是什么以及如何在 Crypto++ 中复制该算法(使用与 C# 中使用的算法相同的算法进行加密 Public 密钥 - 我还不能从后端提取它)

OAEP 值在您的代码示例中不可见,因此如果没有条件我无法回答。

如果 OAEPfalse,则 C# 代码正在执行 RSAES-PKCS1-v1_5。 CryptoPP 等价物是 RSAES_PKCS1v15_Encryptor/RSAES_PKCS1v15_Decryptor.

如果 OAEPtrue 那么 C# 代码正在执行 RSAES-OAEP with SHA-1 as the PRF. The CryptoPP equivalent is RSAES_OAEP_SHA_Encryptor/RSAES_OAEP_SHA_Decryptor (see the example).

您的代码似乎在执行原始 RSA。原始 RSA 很危险(https://rdist.root.org/2009/10/06/why-rsa-encryption-padding-is-critical/,许多其他)。如果要在您遵守的协议上发明/指定一些其他填充方案,公开它的库主要是试图不妨碍您。

.NET 不公开原始 RSA。