c# encryption: IV. public key encryption and signature

1, Public key encryption

1. Overview

Public key encryption is asymmetric, so different keys are required for encryption and decryption. The key of symmetric encryption can be a string of arbitrary bytes with appropriate length. However, asymmetric encryption requires a pair of keys.

This key pair contains a public key and a private key. Together they will accomplish the following:

Public key encrypted message

The private key decrypts the message

The party making the key pair will ensure the security of the private key and distribute the public key freely. The characteristic of this encryption technology is that it is impossible to calculate the private key only through the public key. Therefore, if the private key is lost, it cannot be decrypted. On the contrary, if the private key is leaked, the encryption system will not be able to protect it.

Public key handshake can enable two computers to communicate safely in the public network without reaching agreement or sharing security information in advance.

To illustrate the steps, suppose that the computer Origin wants to send a confidential message to another computer Target:

1. The Target computer generates a public / private key pair and distributes the public key to Origin.

2. Origin encrypts the confidential message with Target's public key and sends it to Target.

3. Target decrypts confidential messages using the private key.

Eavesdroppers can obtain the following data:

1. Target's public key

2. Encrypted message using Target's public key

However, the encrypted message cannot be decrypted without the private key of the Target.

This approach does not prevent man in the middle attacks. In other words, Origin cannot know whether the Target is a malicious attacker. In order to verify the recipient, the sender needs to know the recipient's public key in advance, or verify its identity through the digital certificate of the website.

The encryption message sent by Origin to Target generally contains a newly created symmetric encryption key, which will be used for symmetric encryption in subsequent communications. In this way, the subsequent communication in this session does not need to use the Origin public key. This is because symmetric encryption algorithm is more suitable for handling large messages. This protocol is more secure if a new public / private key pair is generated in each session, because both sides of the communication do not need to store any key.

Public key encryption algorithm requires that the encrypted information is less than the length of the key, so it is more suitable for encrypting a small amount of data (such as symmetric encrypted key). If the length of the data trying to encrypt is greater than half of the key length, an exception will be thrown, so segmented encryption is required if the data length is too large.

        . NET Framework provides many asymmetric encryption algorithms. RSA algorithm is the most popular.

2. RSA encryption demo-1, no public or private key specified

byte[] data = { 5,6,8,4,10 };
using (var rsa = new RSACryptoServiceProvider())
{
    byte[] encrypted = rsa.Encrypt(data, true);
    byte[] decrypted = rsa.Decrypt(encrypted, true);
}

Since no public key or private key is specified, the encryption program will automatically generate a key pair with a length of 1024 bits by default. We can specify a longer key in 8-byte increments in the constructor. For applications with high security requirements, 2048 bit key length shall be selected:

var rsa = new RSACryptoServiceProvider(2048)

3. Generate key pair

Calling the ToXmlString method for the first time will force a new key pair to be generated. fasle is only the public key, true bit public key and private key.

using (var rsa = new RSACryptoServiceProvider())
{
    File.WriteAllText("PublicKeyOnly.xml", rsa.ToXmlString(false));
    File.WriteAllText("PublicPrivate.xml", rsa.ToXmlString(true));
}

4. RSA encryption demo-2, specifying the public and private keys

Use the public key and private key generated above for encryption and decryption.

byte[] data = Encoding.UTF8.GetBytes("A short message");
string PublicKeyOnly = File.ReadAllText("PublicKeyOnly.xml");
string PublicPrivate = File.ReadAllText("PublicPrivate.xml");

byte[] encrypted;
byte[] decrypted;

//encryption
using (var rsaPublicOnly = new RSACryptoServiceProvider())
{
    rsaPublicOnly.FromXmlString(PublicKeyOnly);
    encrypted = rsaPublicOnly.Encrypt(data, true);
}

//decrypt
using (var rsaPublicPrivate = new RSACryptoServiceProvider())
{
    rsaPublicPrivate.FromXmlString(PublicPrivate);
    decrypted = rsaPublicPrivate.Decrypt(encrypted, true);
}

5. RSA encryption demo-3, segmented encryption

1024 bit certificate, with a maximum of 117 bytes during encryption and 128 bytes during decryption;
2048 bit certificate. It supports 245 bytes at most during encryption and 256 bytes during decryption.

string PublicKeyOnly = File.ReadAllText("PublicKeyOnly.xml");
string PublicPrivate = File.ReadAllText("PublicPrivate.xml");
string a = "Test Chinese if this is a number and A string of English letters. Is this long enough? Maybe not long enough, maybe too long? ha-ha,Top defect detection and image processing image recognition items are general,It seems to involve the calculation of some linear algebra";
string encrypted, decrypted;

//encryption
using (var rsa = new RSACryptoServiceProvider())
{
    rsa.FromXmlString(PublicPrivate);
    byte[] bytes = Encoding.UTF8.GetBytes(a);
    int encriptedChunckSize = rsa.KeySize / 8 - 11;
    int dataLength = bytes.Length;
    int iterations = dataLength / encriptedChunckSize + 1;

    ArrayList arrayList = new ArrayList();
    for (int i = 0; i < iterations; i++)
    {
        byte[] tempBytes = new byte[encriptedChunckSize];
        System.Buffer.BlockCopy(bytes, encriptedChunckSize * i, tempBytes, 0, (tempBytes.Length* (i + 1) > bytes.Length) ? (bytes.Length - tempBytes.Length * i) : tempBytes.Length);
        byte[] data1 = rsa.Encrypt(tempBytes, false);
        arrayList.AddRange(data1);

    }
    var descrypt = (byte[])arrayList.ToArray(typeof(Byte));
    encrypted = Convert.ToBase64String(descrypt);
}


using (var rsa = new RSACryptoServiceProvider())
{
    //decrypt
    //byte[] buffer = Encoding.UTF8.GetBytes(encrypted);
    //string keys = Encoding.UTF8.GetString(buffer);
    var bytes = Convert.FromBase64String(encrypted);
    rsa.FromXmlString(PublicPrivate);

    int encriptedChunckSize = rsa.KeySize / 8;
    int dataLength = bytes.Length;
    int iterations = dataLength / encriptedChunckSize;

    ArrayList arrayList = new ArrayList();
    for (int i = 0; i < iterations; i++)
    {
        byte[] tempBytes = new byte[encriptedChunckSize];
        System.Buffer.BlockCopy(bytes, encriptedChunckSize * i, tempBytes, 0, (tempBytes.Length * (i + 1) > bytes.Length) ? (bytes.Length - tempBytes.Length * i) : tempBytes.Length);
        arrayList.AddRange(rsa.Decrypt(tempBytes, false));
    }

    var descrypt = (byte[])arrayList.ToArray(typeof(Byte));
    decrypted = Encoding.UTF8.GetString(descrypt).Trim();
}

Other code references

C# RSA segmented encryption and decryption - FrankYou - blog Park RSA encryption and decryption: 1024 bit certificate, with a maximum of 117 bytes during encryption and 128 bytes during decryption; 2048 bit certificate. It supports 245 bytes at most during encryption and 256 bytes during decryption. Maximum number of bytes supported during encryption: Certificate bits / 8 - 11 (e.g. 204)https://www.cnblogs.com/frankyou/p/5993756.html

6. Digital signature

The public key algorithm can digitally sign messages or documents. A signature is similar to a hash value, but the hash value is encrypted with a private key to prevent forgery, and the public key is used to verify the digital signature. For example:

To make a digital signature, first hash the data, and then encrypt the hash value with asymmetric encryption algorithm. Because the length of hash value is fixed and small, even large documents can be digitally signed quickly (public key encryption is much more computationally expensive than hash algorithm). If necessary, you can also hash the data manually, then call SignHash instead of SignData:

The SignHash method needs to provide information about the hash algorithm. CryptoConfig. The mapnametooid method can query this information with a user-friendly name (such as "SHA1").

The RSACryptoServiceProvider will create a signature that matches the length and key. At present, the signature length generated by mainstream algorithms will not be less than 128 bytes (for example, generate product activation code).

In order to add a digital signature more efficiently, the receiver must know and trust the sender's public key. This can be achieved by communicating in advance, pre configuring or saving the website certificate. The website certificate contains the sender's public key and name, and it itself will be signed by an independent trusted authority. System. Security. Cryptography. The types in the x509certificates namespace can be used to handle certificate related operations.

Keywords: C# Encryption rsa

Added by jrws on Sun, 09 Jan 2022 09:27:03 +0200