Search code examples
c#encryptionrsa

Why is it all RSA algorithms, but the results are completely different?


I am learning rsa encryption and decryption recently. I try to encrypt some data in C# and verify the result. I found that the output result of the code I wrote in C# is inconsistent with the output result of some RSA online computing websites. Is this normal?

First I generated private key and public key using openssl:

private key:

-----BEGIN RSA PRIVATE KEY-----
MIICXAIBAAKBgQDTlCZFucurE+QNupniPUXz5RwNdhRAplB+jd51U4NTcpDl4AL3
LppKdRxEyt4FlvLiE66tmonEJTc4BcaRurxxXOuY+0IS4l28FynYT/yDpdoiop0J
f2NCa8V5nCBISKp1Lgvz7AbHBw+3KNCF1UdrOeRsr/GBOSXosmTzPMRUNwIDAQAB
AoGALyDC3akjCrplhAFaoaBQYqFX/E+e9z+Uknv7X1r416+fQvUA9Bo3V/p6D4C4
r7oN4/nKYPUZVs2LXTk8H93ed2IikcevB4vnHgO3ym5vt+KyrmCemwyV/rbA5kg5
sDvMqXJr2/FfQtLR3GLumZJN2r5Hcq1Kgo3tgx7gsoZm4JECQQDxCoSeyWPuyQKx
3aHWJkVybmHD5d6HuFFyaM4pOAOXaGrtkZSrh3c+NJhAuW62d+oE8kwCNymz74G5
Pq+5yRftAkEA4LWOGKAeidLFM2RON3DFMNDH3KEB4C9144SilzVr6dDEOgBqdCya
+vazx2J0OV8Bm5ocqtTBOT4ZmD7BXtTQMwJASEwYVSwgnjmKZmEMrpfSEq2LA2AK
K/kb7M4EsBZN9XbrQ5B74CsEmBLca+VykKZM+ejW5X84MfEvnqlvubDYTQJBAKAv
7OcTJhH8JcY4CCYvhvMAsqlOQecODk0t3TZLx+z7fRcX+stsjOLBAXHudon7d0r0
duE1H7Vt1pMYkYLH1M8CQEZ76ME68DE7DkTPhBvPL22O898Kt89bCen68EVv3kl8
7k4XsAGrLldX6xvV/oeLDI+uRiYqZylS2PFY3XcT3f8=
-----END RSA PRIVATE KEY-----

public key :

-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDTlCZFucurE+QNupniPUXz5RwN
dhRAplB+jd51U4NTcpDl4AL3LppKdRxEyt4FlvLiE66tmonEJTc4BcaRurxxXOuY
+0IS4l28FynYT/yDpdoiop0Jf2NCa8V5nCBISKp1Lgvz7AbHBw+3KNCF1UdrOeRs
r/GBOSXosmTzPMRUNwIDAQAB
-----END PUBLIC KEY-----

this is my test c# codes:

string InputText = "ABCDEFG123456";

{
    string sk = File.ReadAllText("D:\\rsa_private_key.pem");
    string sk2 = sk.Replace("\n", "");

    var rsa = RSA.Create();

    rsa.ImportFromPem(sk.ToArray());
    var text = Convert.ToBase64String(rsa.Encrypt(Encoding.UTF8.GetBytes(InputText), RSAEncryptionPadding.Pkcs1));

    Console.WriteLine(text);

}

the output is :

WecnM6F8+oVuOR7OhOMeDwzrfWsYeW0uTMZC2AJ9a6AhzVIZgPhVZv1heMPN8yfhnBo03Vh/hzUXGeUZpAO7PVQ7mFKCRARy35cTcGxTpGLEhhAUe1cqj92rO5zlm/fIQOi0PraeduqD2HRQOSHz3eq71oHdy22s5sb4WNwyTj8=

Then, I did the same again on this site:

enter image description here

the output is :

btZnhouzYuYk3grzhI9MJinlrmRmsVhmUBUpW0pKpXXZ2VPgw97Cx869+r7WMDQFRG34jELDIpeADNxJeUnnOwm1J5z489THaYO6pqQ7UWeXyMhus05RSPcNDjvJjjJcZ/FyxUNhd7JNqaioTQB8SKo+p3BD/VkMH0tl/I90WTc=

In addition, I also tested it on some other tools, and their output is consistent with the website, and inconsistent with my demo, so I want to ask, what is wrong with my C# code? Or is the rsa encryption algorithm itself not stable?

One difference I can think of might be that the private key I pasted into the website is a string with newlines stripped.


Solution

  • I use openssl, it generate the same result with the website:

    std::string decrypt_string(const void* data, size_t length)
    {
        BIO* bio = BIO_new_mem_buf(pk.c_str(), (int)pk.size());
        
        RSA* rsa = NULL;
        PEM_read_bio_RSA_PUBKEY(bio, &rsa, 0, 0);
        
        char buf[1024] = {0};
        
        int ret = RSA_public_decrypt(0x80, (const unsigned char*)data, (unsigned char*)buf, rsa, RSA_PKCS1_PADDING);
        
        if(ret == -1)
        {
            BIO_free(bio);
            
            printf("decrypt error:%d\n", ret);
            return "Error";
        }
        
        BIO_free(bio);
        
        std::string str = buf;
        
        return buf;
    }
    
    std::string encrypt_string(const std::string& str)
    {
        RSA* rsa = NULL;
        BIO* bio = BIO_new_mem_buf(sk.c_str(), (int)sk.size());
        
        PEM_read_bio_RSAPrivateKey(bio, &rsa, 0,0);
        
        assert(rsa!=NULL);
        
        char buf[1024];
        int ret = RSA_private_encrypt((int)str.length(), (const unsigned char *)str.data(), (unsigned char*)buf, rsa, RSA_PKCS1_PADDING);
        
        if(ret == -1)
        {
            BIO_free(bio);
            
            printf("decrypt error:%d\n", ret);
            return "Error";
        }
        
        BIO_free(bio);
        
        std::string str2 = base64_encode((unsigned char const*)buf, ret);
        
        return str2;
    }