RSA algorithm is the first algorithm that can be used in both encryption and digital signature, and it is easy to understand and operate. RSA is the most widely studied public-key algorithm, from the proposed to now nearly 20 years, experienced a variety of attacks, gradually accepted by people, generally considered to be one of the best public key schemes. RSA security relies on the factorization of large number of factors, but it doesn't prove that the difficulty of deciphering RSA is equivalent to the difficulty of large number decomposition.
RSA's security relies on large-number decomposition. Both public and private keys are functions of two large primes (greater than 100 decimal digits). It is speculated that the difficulty of inferring plaintext from a key and cipher is equivalent to breaking the product of two large primes.
The generation of the key pair. Select two large primes, p and Q. Calculation:
n = p * Q
Then randomly select the Encryption key E (PS: The most commonly used e values are 3, 17 and 65537, Microsoft is the use of 65537, with 3 of any of the security issues do not exist), requirements E and (p-1) * (q-1) coprime. Finally, the Euclid algorithm is used to compute the decryption key D, which satisfies
E * d = 1 (mod (p-1) * (q-1))
where N and D are also coprime. The numbers e and n are public keys and D is the private key. Two primes p and Q no longer needed, should be discarded, don't let anyone know.
When encrypting information m (binary representation), first divides m into equal length blocks m1, M2,..., mi, blocks long s, where 2^s <= N, s as large as possible. The corresponding ciphertext is:
ci = mi^e (mod n) (a)
The following calculations are made when decrypting:
mi = ci^d (mod n) (b)
. NET provides commonly used cryptographic algorithm classes, RSA-enabled classes are RSACryptoServiceProvider (namespaces: System.Security.Cryptography), but only public key cryptography and private key decryption are supported. The RSACryptoServiceProvider classes include: Modulus, Exponent, P, Q, DP, DQ, inverseq, D, etc. 8 attributes, where modulus and Exponent are public keys, and modulus and D are the private keys, The RSACryptoServiceProvider class provides methods for exporting public keys, and also provides methods for exporting private keys, but the exported private key contains the above 8 properties, and it is obvious that it is not feasible to use RSACryptoServiceProvider to implement the private key to encrypt the public key.
From the principle of RSA, public key encryption private key decryption and private key encryption public key decryption should be equivalent, in some cases, such as the sharing of software encryption, we need to use the private key to encrypt the registration code or registration files, to the user, the user with the public key to decrypt the registration code or registration documents for
I use the internet to find a C # version of a large integer class BigInteger (I think this is the most efficient one I found a C # version of a large integer class) to implement the private key encryption public key encryption (in fact, also fully support the public rental encryption private key decryption), but did not use the class BigInteger large Instead, use the class RSACryptoServiceProvider directly to generate large primes. Where the cryptographic functions and decryption functions are implemented as follows:
/**//*
Function: Encrypts the specified string source with the specified private key (N,D)
*/
Private string encryptstring (string source, BigInteger D, BigInteger N)
... {
int len = source. Length;
int len1 = 0;
int blocklen = 0;
if ((len% 128) = = 0)
Len1 = len/128;
else
Len1 = len/128 + 1;
String block = "";
String temp = "";
for (int i = 0; i < len1 i++)
... {
if (len >= 128)
Blocklen = 128;
else
Blocklen = len;
block = source. Substring (i * 128, Blocklen);
byte[] Otext = System.Text.Encoding.Default.GetBytes (block);
BigInteger bitext = new BigInteger (otext);
BigInteger bientext = Bitext.modpow (d, N);
String temp1 = Bientext.tohexstring ();
temp = Temp1;
Len-= Blocklen;
}
Return temp;
}
/**//*