The most easy to understand RSA encryption and decryption Guide

preface RSA encryption algorithm is an asymmetric encrypt...

preface

RSA encryption algorithm is an asymmetric encryption algorithm. In short, it uses one key for encryption and another key for decryption.

Because the encrypted key is public, also known as public key, the decrypted key is not public, so it is called private key.

secret key

There are many articles about RSA encryption, but almost all of them only introduce the usage of RSACryptoServiceProvider class. If you just walk around, it's OK. But if you really want to use it, you will find that you don't have a key string...

Let's learn encryption step by step from getting the key string.

Key string

Every computer that has visual studio installed can find a file - makecert.exe .

My computer makecert.exe Address: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\makecert.exe

makecert.exe Is the program used to generate the certificate. We can borrow the program to obtain the key string.

Write the CreateCertWithPrivateKey function to generate the certificate. The code is as follows:

public static bool CreateCertWithPrivateKey(string subjectName, string makecertPath) { subjectName = "CN=" + subjectName; string param = " -pe -ss my -n \"" + subjectName + "\" "; try { Process p = Process.Start(makecertPath, param); p.WaitForExit(); p.Close(); } catch (Exception e) { return false; } return true; }

Call the certificate generation function. The code is as follows:

string keyName = "Kiba518.Licence";//KEY of certificate var ret = DataCertificate.CreateCertWithPrivateKey(keyName, @"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\makecert.exe");

The certificate just generated is also stored in the certificate store of WINDOWS. Now we can find the certificate in the certificate store through the Key of the certificate, and export it to the out (the password needs to be specified when exporting). The export function code is as follows:

public static bool ExportToPfxFile(string subjectName, string pfxFileName, string password, bool isDelFromStore) { subjectName = "CN=" + subjectName; X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser); store.Open(OpenFlags.ReadWrite); X509Certificate2Collection storecollection = (X509Certificate2Collection)store.Certificates; foreach (X509Certificate2 x509 in storecollection) { if (x509.Subject == subjectName) { byte[] pfxByte = x509.Export(X509ContentType.Pfx, password); using (FileStream fileStream = new FileStream(pfxFileName, FileMode.Create)) { // Write the data to the file, byte by byte. for (int i = 0; i < pfxByte.Length; i++) fileStream.WriteByte(pfxByte[i]); // Set the stream position to the beginning of the file. fileStream.Seek(0, SeekOrigin.Begin); // Read and verify the data. for (int i = 0; i < fileStream.Length; i++) { if (pfxByte[i] != fileStream.ReadByte()) { fileStream.Close(); return false; } } fileStream.Close(); } if (isDelFromStore == true) store.Remove(x509); } } store.Close(); store = null; storecollection = null; return true; }

Call the export function. The code is as follows:

DataCertificate.ExportToPfxFile(keyName, "Kiba518.pfx", "123456", true);

After running the export function, open the Debug folder, and you can see that the certificate has been successfully exported, as shown in the following figure:

After the certificate is exported, we can get the public key and private key by reading the certificate information.

X509Certificate2 x509 = X509Certificate2("Kiba518.pfx", "123456", X509KeyStorageFlags.Exportable); string publickey = x509.PublicKey.Key.ToXmlString(false);//Public key acquisition string privatekey = x509.PrivateKey.ToXmlString(true);//Private key acquisition

The public key and private key are as follows:

Encryption and decryption

After getting the key string, we create the encryption and decryption function of RSA, the code is as follows:

//encryption public static string RSADecrypt(string xmlPrivateKey, string enptStr) { RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); provider.FromXmlString(xmlPrivateKey); byte[] rgb = Convert.FromBase64String(enptStr); byte[] bytes = provider.Decrypt(rgb, RSAEncryptionPadding.OaepSHA1); return new UnicodeEncoding().GetString(bytes); } //decrypt public static string RSAEncrypt(string xmlPublicKey, string enptStr) { RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); provider.FromXmlString(xmlPublicKey); byte[] bytes = new UnicodeEncoding().GetBytes(enptStr); return Convert.ToBase64String(provider.Encrypt(bytes, RSAEncryptionPadding.OaepSHA1)); }

Then we test encryption and decryption. The test function is as follows.

public static void RsaTest() { string myname = "my name is Kiba518!"; Console.WriteLine($"Content:"); string enStr = RSAEncrypt(publicKey, myname); Console.WriteLine($"Encryption string:"); string deStr = RSADecrypt(privateKey, enStr); Console.WriteLine($"Decrypt string:"); }

As a result, encryption and decryption are successful, as shown in the following figure:

Long character segmented encryption

There is a byte limit for Rsa encryption, that is, if the string to be encrypted is too long, the system will throw an exception:[ System.Security.Cryptography.CryptographicException: "incorrect length]

The specific restrictions of Rsa encryption are as follows:

The number of bytes to be encrypted cannot exceed the length of the key divided by 8 and subtracted by 11 (that is, RSAC ryptoServiceProvider.KeySize /8 - 11), and the number of encrypted bytes is exactly the length of the key divided by 8 (that is, RSAC ryptoServiceProvider.KeySize / 8).

Segmented encryption

To solve the exception of long character encryption, we adopt the method of segmented encryption for string encryption. The code is as follows:

//encryption public static String SubRSAEncrypt(string xmlPublicKey, string enptStr) { RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); provider.FromXmlString(xmlPublicKey); Byte[] bytes = Encoder.GetBytes(enptStr); int MaxBlockSize = provider.KeySize / 8 - 11; //Encryption block maximum length limit ​ if (bytes.Length <= MaxBlockSize) return Convert.ToBase64String(provider.Encrypt(bytes, false)); ​ using (MemoryStream PlaiStream = new MemoryStream(bytes)) using (MemoryStream CrypStream = new MemoryStream()) { Byte[] Buffer = new Byte[MaxBlockSize]; int BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize); ​ while (BlockSize > 0) { Byte[] ToEncrypt = new Byte[BlockSize]; Array.Copy(Buffer, 0, ToEncrypt, 0, BlockSize); ​ Byte[] Cryptograph = provider.Encrypt(ToEncrypt, false); CrypStream.Write(Cryptograph, 0, Cryptograph.Length); ​ BlockSize = PlaiStream.Read(Buffer, 0, MaxBlockSize); } ​ return Convert.ToBase64String(CrypStream.ToArray(), Base64FormattingOptions.None); } } //decrypt public static String SubRSADecrypt(string xmlPublicKey, string enptStr) { RSACryptoServiceProvider provider = new RSACryptoServiceProvider(); provider.FromXmlString(xmlPublicKey); Byte[] bytes = Convert.FromBase64String(enptStr); int MaxBlockSize = provider.KeySize / 8; //Decryption block maximum length limit ​ if (bytes.Length <= MaxBlockSize) return Encoder.GetString(provider.Decrypt(bytes, false)); ​ using (MemoryStream CrypStream = new MemoryStream(bytes)) using (MemoryStream PlaiStream = new MemoryStream()) { Byte[] Buffer = new Byte[MaxBlockSize]; int BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize); ​ while (BlockSize > 0) { Byte[] ToDecrypt = new Byte[BlockSize]; Array.Copy(Buffer, 0, ToDecrypt, 0, BlockSize); Byte[] Plaintext = provider.Decrypt(ToDecrypt, false); PlaiStream.Write(Plaintext, 0, Plaintext.Length); BlockSize = CrypStream.Read(Buffer, 0, MaxBlockSize); } return Encoder.GetString(PlaiStream.ToArray()); } }

Write the segmented encryption test function as follows:

public static void SubRsaTest() { string myname = "my name is Kiba518!my name is Kiba518!my name is Kiba518!my name is Kiba518!my name is Kiba518!my name is Kiba518!my name is Kiba518!"; Console.WriteLine($"Content:"); string enStr = SubRSAEncrypt(publicKey, myname); Console.WriteLine($"Encryption string:"); string deStr = SubRSADecrypt(privateKey, enStr); Console.WriteLine($"Decrypt string:"); }

As a result, encryption and decryption are successful, as shown in the following figure:

About Certificates

The certificate Kiba518.pfx created in this paper is the certificate used by https. In other words, the certificate of https is an Rsa encryption and decryption file.

Of course, the formal certificates that can be recognized by major websites on the Internet need to be certified by an authoritative organization. This organization is called CA, and the certificates issued by this organization are. crt suffixes. Our pfx suffixes are called personal information exchange certificates.

In fact, there is no difference between them, that is, the shell of the set is different. There are many attributes in the shell of the crt certificate, such as the certification authority, validity period and so on. But the core content of the two certificates is the same, both are Rsa encryption and decryption files.

Let's briefly understand the import of certificates.

Import certificate

Enter mmc in the run window (window+r) to open the microsoft Management Console.

Then operate file - > Add / delete snap in, select the certificate in the available snap in and click Add.

After adding the snap in, a certificate root node will be added to the root node of the right console, as shown in the following figure:

Then, we expand the node, find the person certificate node, and right click all tasks import.

Then follow the wizard prompts to import the certificate.

Note that you need to browse the Import Certificate dialog box. The default import is crt type. We need to click the drop-down menu and select the person information exchange option, as shown in the following figure.

----------------------------------------------------------------------------------------------------

The basic use of Rsa encryption and decryption has been introduced.

The code has been transmitted to Github, welcome to download.

Github address: https://github.com/kiba518/RsaDemo

----------------------------------------------------------------------------------------------------

Note: This article is original, any form of reprint please contact the author to obtain authorization and indicate the source!
If you think this article is not bad, please click [recommend] below, thank you very much!

https://www.cnblogs.com/kiba/p/13141981.html

21 June 2020, 23:57 | Views: 5447

Add new comment

For adding a comment, please log in
or create account

0 comments