# RSA Cryptography

## RSA Highlights

• The plaintext‘s length must be less than or equal to the modulus’s size minus 88-bit padding, while OAEP padding typically adds 42 bytes. (1960 bits at most, given a 2048-bit modulus)
• The ciphertext’s length equals the modulus’s size (p x q). (A 128-bit plaintext generates a 2048-bit ciphertext, given a 2048-bit modulus)
• Because the size of hash values and symmetric keys is typically less than 512 bits, asymmetric cryptography is suitable for key exchange and digital signatures.
• However, because of the lack of forward secrecy support, RSA nowadays is deemed inappropriate for key exchange.
• “Forward secrecy (FS), also known as perfect forward secrecy (PFS), is a feature of specific key-agreement protocols that gives assurances that session keys will not be compromised even if long-term secrets used in the session key exchange are compromised.” (Wikipedia)

## PKCS #1

``````         RSAPublicKey ::= SEQUENCE {
modulus           INTEGER,  -- n
publicExponent    INTEGER   -- e
}

RSAPrivateKey ::= SEQUENCE {
version           Version,
modulus           INTEGER,  -- n
publicExponent    INTEGER,  -- e
privateExponent   INTEGER,  -- d
prime1            INTEGER,  -- p
prime2            INTEGER,  -- q
exponent1         INTEGER,  -- d mod (p-1)
exponent2         INTEGER,  -- d mod (q-1)
coefficient       INTEGER,  -- (inverse of q) mod p
otherPrimeInfos   OtherPrimeInfos OPTIONAL
}``````

## Sample Code

The following is a snippet of C# code in LINQPad that demonstrates RSA Cryptography:

``````System
System.Security.Cryptography

void Main()
{
string message =
"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"+
"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"+
"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF"+
"0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF01234";
(message.Length * 8).Dump("message.Length"); //1960 bits

RSAParameters key = RsaEncryption.GenerateKey(2048);
key.Dump("Key per PKCS #1");

var encryptedData = RsaEncryption.Encrypt(message, key);
(encryptedData.Length * 8).Dump("encryptedData.Length");

var decryptedData = RsaEncryption.Decrypt(encryptedData, key);
(decryptedData.Length * 8).Dump("decryptedData.Length");

/*
string encryptedMessage = Convert.ToBase64String(encryptedData);
string decryptedMessage = Encoding.UTF8.GetString(RsaEncryption.Decrypt(encryptedData, key));
Console.WriteLine("Encrypted message: " + encryptedMessage);
Console.WriteLine("Decrypted message: " + decryptedMessage);
*/

//Digital Signature
var hash = Sha256Hash.ComputeHash(message);
BitConverter.ToString(hash).Dump("hash");
(hash.Length * 8).Dump("hash.Length");

var signature = DigitalSignature.Sign(hash, key);
bool verified = DigitalSignature.Verify(hash, signature, key);

(signature.Length * 8).Dump("signature.Length");
verified.Dump("verified");
//Console.WriteLine("Signature: " + signature);
//Console.WriteLine("Verified: " + verified);
}

// Define other methods and classes here
public class Sha256Hash
{
public static byte[] ComputeHash(string message)
{
byte[] hashValue;
using (SHA256 sha256 = SHA256.Create())
{
hashValue = sha256.ComputeHash(Encoding.UTF8.GetBytes(message));
}

return hashValue;
}
}

public class RsaEncryption
{
public static byte[] Encrypt(string message, RSAParameters key)
{
byte[] encryptedData;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(key);
encryptedData = rsa.Encrypt(Encoding.UTF8.GetBytes(message), false);
}

return encryptedData;
}

public static byte[] Decrypt(byte[] ciphertext, RSAParameters key)
{
byte[] decryptedData;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(key);
decryptedData = rsa.Decrypt(ciphertext, false);
}

return decryptedData;
}

public static RSAParameters GenerateKey(int keySzie)
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(keySzie);
return rsa.ExportParameters(true);
}
}

public class DigitalSignature
{
public static byte[] Sign(byte[] hash, RSAParameters key)
{
byte[] signature;
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(key);
signature = rsa.SignHash(hash, CryptoConfig.MapNameToOID("SHA256"));
}

return signature;
}

public static bool Verify(byte[] hash, byte[] signature, RSAParameters key)
{
using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider())
{
rsa.ImportParameters(key);
return rsa.VerifyHash(hash, CryptoConfig.MapNameToOID("SHA256"), signature);
}
}
}``````