2

Please help me identify problem in following RSA Encryption code

public static void Test()
{
    CspParameters cspParams = new CspParameters { ProviderType = 1 };
    RSACryptoServiceProvider rsaProvider = new RSACryptoServiceProvider(1024, cspParams);

    var PublicKey = Convert.ToBase64String(rsaProvider.ExportCspBlob(false));  //I have to save it as string in some json/app.config configuration file
    var PrivateKey = Convert.ToBase64String(rsaProvider.ExportCspBlob(true));  //I have to save it as string in some json/app.config configuration file
    
    var encrypt = EncryptText(PublicKey,  Encoding.UTF8.GetBytes(FromSomeFile()));
    
    var decrypt = DecryptData(PrivateKey, encrypt);
}

static byte[] EncryptText(string publicKey, byte[] dataToEncrypt)
{   
    byte[] encryptedData;
    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
    {                
        rsa.ImportCspBlob(Convert.FromBase64String(publicKey));             
        encryptedData = rsa.Encrypt(dataToEncrypt, false);
    }
    return encryptedData;
}

// Method to decrypt the data withing a specific file using a RSA algorithm private key   
static string DecryptData(string privateKey, byte[] dataToDecrypt)
{
    
    // Create an array to store the decrypted data in it   
    byte[] decryptedData;
    using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
    {
        rsa.ImportCspBlob(Convert.FromBase64String(privateKey));              
        decryptedData = rsa.Decrypt(dataToDecrypt, false);
    }           
    
    return Encoding.UTF8.GetString(decryptedData, 0, decryptedData.Length); ;
}
Kamran Shahid
  • 3,954
  • 5
  • 48
  • 93
  • 1
    How can `EncryptText()` accept `"Kamran"` as its `dataToEncrypt` argument, which is of type `byte[]`? - please show your actual code. – 500 - Internal Server Error Jul 13 '20 at 20:42
  • there was a typo when creating this post. – Kamran Shahid Jul 14 '20 at 05:50
  • 1
    Does that solve the problem? Because it' s running on my machine. If not, please post the exact error message / stacktrace and .NET version. – Topaco Jul 14 '20 at 06:18
  • I have a big file for encryption. Like 1000 or more bytes. Can you check it with big file – Kamran Shahid Jul 14 '20 at 13:22
  • 2
    This isn't possible with RSA, see [How to encrypt large file with RSA?](https://stackoverflow.com/a/40244430/9014097) – Topaco Jul 14 '20 at 14:33
  • Please try same code with some large file may 2000 bytes. your above mentioned algorithm looks like Hybrid Encryption. I was just thinking having public key at generation end and sharing private key at client end where decryption will be take place – Kamran Shahid Jul 14 '20 at 14:38
  • 2
    I don't need to try anything. It's _not_ possible! With a 1024 bits RSA key a maximum of 128 bytes can be encrypted (depending on the padding even less, e.g. for PKCS#1 v1.5 only 117 bytes as in your case), see [here](https://stackoverflow.com/a/5868456/9014097). – Topaco Jul 14 '20 at 14:58
  • Thanks @Topaco , Will analyse what key size i should try or might need to try something else to encrypt my 2/3 KB file – Kamran Shahid Jul 14 '20 at 15:05
  • 2
    Keep in mind that for larger RSA keys, the performance decreases. You can test a 8192 bits key (1024 bytes, maximum payload for Pkcs#1 v1.5: 1013 bytes). Usually, a symmetric encryption like AES is applied for larger data volumes. If necessary, RSA can be used to exchange the symmetric key securely (hybrid encryption). This is described in the link posted first. – Topaco Jul 14 '20 at 15:18
  • Yes. For the same case I have done some hybrid encryption related thing some years back. now looks like i have to do same thing. @Topaco please add your comment as answer so i will accept it. Thanks – Kamran Shahid Jul 14 '20 at 16:28

1 Answers1

2

RSA can only be used to encrypt messages whose length is less than the modulus. How much smaller depends on the padding, e.g. 11 bytes in case of PKCS#1 v1.5, s. here. In the case of OAEP, the number of bytes claimed by padding depends on the digest used, s. here. The details are described in RFC8017, RSAES-PKCS1-v1_5 and RSAES-OAEP.
For completeness: RSA without padding (textbook RSA) allows the encryption of messages up to exactly the length of the modulus. In practice, however, padding must always be used for security reasons, so textbook RSA is not a real option.

The posted code uses an RSA key of 1024 bits and PKCS#1 v1.5 padding. The maximum size of the message to be encrypted is therefore 117 bytes. Larger messages throw a CryptographicException (Bad Length). That is the reason for your issue.

A 8192 bits (1024 bytes) key would theoretically allow messages up to 1013 bytes in length to be encrypted with PKCS#1 v1.5 Padding. However, the performance decreases strongly with increasing key size, s. here.

Symmetric encryption is more performant than asymmetric encryption. Therefore, in practice larger data volumes are encrypted using symmetric encryption, e.g. AES. However, symmetric encryption has the problem that the communication partners have to exchange the symmetric key. Asymmetric encryption, e.g. RSA, is typically used for this purpose (hybrid encryption), since only the public keys are needed for encryption (which can therefore be exchanged over an insecure channel). However, to prevent a deceptive replacement of the public keys (man in the middel attack), a complex public key infrastructure is generally necessary.

Community
  • 1
  • 1
Topaco
  • 40,594
  • 4
  • 35
  • 62