Those commonly used encryption algorithms in C #

Posted by tmh766 on Fri, 11 Feb 2022 12:19:05 +0100

preface
This article mainly explains the encryption algorithms that C# commonly use.

Source code of this article
The source code used in this article is that you have finished sorting, and you can obtain it in the following ways

Small buddy, official account: WeChat official account: programmer zero distance, or scan the public code of the next two dimensional code, reply key: encryption algorithm, you can get all the source resources used in this article.

Pay attention to the official account above and reply to the encryption algorithm.

MD5 encryption
MD5 encryption is the most common encryption method. Because MD5 is irreversible, many system passwords are saved with MD5 encryption.

Although MD5 cannot be decoded, because the string encrypted by MD5 is fixed, in theory, we only need to establish a huge database and encrypt all strings, then we can decode all MD5 ciphertexts.

Although it is unrealistic to build a database that can decode all MD5, a database with 50 billion or 60 billion data can decode most strings. After all, in most cases, our passwords are also limited in length.

In practical application, MD5 can be divided into 64 bit and 32-bit encryption, and the code is as follows:

#region MD5 encryption 32 and 64 
public static string GetMd532(string ConvertString)
{
  MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
  string t2 = BitConverter.ToString(md5.ComputeHash(UTF8Encoding.Default.GetBytes(ConvertString)), 4, 8);
  t2 = t2.Replace("-", "");
 
  return t2;
} 
public static string Get64Md5(string str)
{
  string cl = str;
  string pwd = "";
  var md5 = MD5.Create();
  byte[] s = md5.ComputeHash(Encoding.UTF8.GetBytes(cl)); 
  for (int i = 0; i < s.Length; i++)
  {
    pwd = pwd + s[i].ToString("X2");
  } 
  return pwd;
} 
#endregion

Let's run the encryption function.

Console.WriteLine($"MD5-64:{ MD5Helper.Get64Md5("Kiba518")}");
Console.WriteLine($"MD5-32:{ MD5Helper.Get32Md5("Kiba518")}");

The results are shown in the figure below:

SHA1 encryption
SHA1 encryption algorithm is similar to MD5 encryption, which is irreversible, but the algorithm is different. Therefore, like MD5, it is easy to be decoded by big data.

The code is as follows:

private static readonly Encoding Encoder = Encoding.UTF8;
public static String Sha1(String content )
{
  try
  {
    SHA1 sha1 = new SHA1CryptoServiceProvider();//Create SHA1 object
    byte[] bytes_in = Encoder.GetBytes(content);//Convert the string to be encrypted to byte type
    byte[] bytes_out = sha1.ComputeHash(bytes_in);//Hash operation
    sha1.Dispose();//Release all resources used by the current instance
    String result = BitConverter.ToString(bytes_out);//Convert the operation result to string type
    result = result.Replace("-", "").ToUpper();
    return result;
  }
  catch (Exception ex)
  {
    return ex.Message;
  }
}

Run the encryption function, and the result is shown in the figure below:

Base64 encryption
To be exact, Base64 is a kind of encoding, not encryption. Usually, the string encoded by Base64 will be used to transmit data. However, because the string encoded by Base64 is unreadable, many people also use it as an encryption algorithm.

The code is as follows:

private static readonly Encoding Encoder = Encoding.UTF8;
public static string EncodeBase64(string source)
{
  string target = "";
  byte[] bytes = Encoder.GetBytes(source);
  try
  {
    target = Convert.ToBase64String(bytes);
  }
  catch
  {
    target = source;
  }
  return target;
}
public static string DecodeBase64(string result)
{
  string decode = "";
  byte[] bytes = Convert.FromBase64String(result);
  try
  {
    decode = Encoder.GetString(bytes);
  }
  catch
  {
    decode = result;
  }
  return decode;
}

Run the Base64 encoding function.

string base64Str = Base64Helper.EncodeBase64("Kiba518");
Console.WriteLine($"SHA1 code:{ base64Str}");
Console.WriteLine($"SHA1 decode:{ Base64Helper.DecodeBase64(base64Str)}");

The results are shown in the figure below:

Des encryption
DES encryption algorithm is to keep the key secret, while the public algorithm is that only people with the same key can decrypt it.

DES encryption algorithm requires the key to be 8 characters, such as abcdefgh.

The code is as follows:

public static string Encrypt(string stringToEncrypt, string shortKey)
{
  DESCryptoServiceProvider des = new DESCryptoServiceProvider();
  byte[] inputByteArray = Encoding.GetEncoding("UTF-8").GetBytes(stringToEncrypt);
  des.Key = ASCIIEncoding.UTF8.GetBytes(shortKey);
  des.IV = ASCIIEncoding.UTF8.GetBytes(shortKey);
  MemoryStream ms = new MemoryStream();
  CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
  cs.Write(inputByteArray, 0, inputByteArray.Length);
  cs.FlushFinalBlock();
  StringBuilder ret = new StringBuilder();
  foreach (byte b in ms.ToArray())
  {
    ret.AppendFormat("{0:X2}", b);
  }
  ret.ToString();
  return ret.ToString();
}
public static string Decrypt(string stringToDecrypt, string sKey)
{
  DESCryptoServiceProvider des = new DESCryptoServiceProvider();
 
  byte[] inputByteArray = new byte[stringToDecrypt.Length / 2];
  for (int x = 0; x < stringToDecrypt.Length / 2; x++)
  {
    int i = (Convert.ToInt32(stringToDecrypt.Substring(x * 2, 2), 16));
    inputByteArray[x] = (byte)i;
  }
  des.Key = ASCIIEncoding.UTF8.GetBytes(sKey);
  des.IV = ASCIIEncoding.UTF8.GetBytes(sKey);
  MemoryStream ms = new MemoryStream();
  CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
  cs.Write(inputByteArray, 0, inputByteArray.Length);
  cs.FlushFinalBlock();
  StringBuilder ret = new StringBuilder();
  return System.Text.Encoding.Default.GetString(ms.ToArray());
}

As shown in the code, we use the DESCryptoServiceProvider class for DES encryption.

The Mode property of the DESCryptoServiceProvider class can specify the encryption operation Mode.

The encryption operation mode is as follows:

CBC: cipher block chain mode.
ECB: electronic codebook mode.
OFB: output feedback mode.
CFB: password feedback mode.
CTS: password text theft mode.
The default encryption operation mode in C# is CBC - cipher block chain mode.

In Java, the default encryption operation mode is ECB - Electronic codebook mode.

That is, if the ciphertext is passed between the C# project and the Java project, the same encryption operation mode must be configured.

The code of DES encryption function is as follows:

string key_8 = "abcdefgh";
string desShortKeyStr = DESHelper.Encrypt("Kiba518", key_8);
Console.WriteLine($"DES encryption:{ desShortKeyStr}");
Console.WriteLine($"DES decrypt:{ DESHelper.Decrypt(desShortKeyStr, key_8)}");

The results are shown in the figure below:

Sometimes, our key is not exactly 8 characters, so we can intercept the first 8 characters as the key.

RSA encryption
RSA encryption adopts the mode of public key encryption and private key decryption. The digital certificate of Https is also encrypted using this mode.

The code is as follows:

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);
}
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));
}

The code of DES encryption function is as follows:

//Encryption public key 
string publicKey = "18+I2j3HU/fXQasRXOWGegP3dG75I/It2n42rgeIATeftBkoQNH73Rz0IYW++arqd0Yy5hFpNkqzY/dOmD+bDXWUheWA0P/dVZf+qeWwVV+iW3lRAU8SmnPcaD35Ic1jMEPFQVeX1zGI2ofD8aGodeSRA4+JKo+KLgyGVGDI+d0=AQAB";
//Decrypt private key 
string privateKey = " 18+I2j3HU/fXQasRXOWGegP3dG75I/It2n42rgeIATeftBkoQNH73Rz0IYW++arqd0Yy5hFpNkqzY/dOmD+bDXWUheWA0P/dVZf+qeWwVV+iW3lRAU8SmnPcaD35Ic1jMEPFQVeX1zGI2ofD8aGodeSRA4+JKo+KLgyGVGDI+d0=AQAB
2EEAI+cO1fyvmGpg3ywMLHHZ1/X3ZrF6xZBNM2AL7bJFVfL8RS8UznUCdsL/R/o1b+lGo1CetlI++n6IvYYwyw==
 
/3muAXWOU3SMKFWSDpHUgeM9kZev0ekQDefRSayXM8q9ItkaWTOJcIN614A0UGdYE6VX1ztPgveQFzm0qJDy9w==NM/i/eGewOmd5IYONFJogq4nOlOKYNz1E6yC/gn1v83qmuvlaevuk+EFggVrHKPhSvxYUOgOao45bSlbsZVE8w==MKU7w91dh3iWw4tfr1SHUWAytglbGi41t2Af0taBSARftUX/pWKR1hHDD0vDKlgzRjJiooIRps966WE8jChliw==YEIfQArVNP27AJn3WOBswHP/+gJ6Bk434MZ80CJONp4b6e+Ilxd2dwloxGKNbGgCyaNJEFI5J8qYSNNe0KqPkw==ZAscSPesqLtS+WlBMkxgy719AGfVbRl+sjQiSwjIvq+3hDjJVUtCs90RO10SDBF0gfhz7f2SRY3ZnXTu5VtPF9KEQyUaY0F6eXwz4YQNzJTI2c1o5SFXZP8Ynqwltg8gNIhMe8bB6nVgASeADBim22DlSFCzmD3vt1gTI8nxmO0=";
string myname = "my name is Kiba518!my name is Kiba518!!!!43"; //Maximum length 43
string rsaStr = RSAHelper.RSAEncrypt(publicKey, myname);
Console.WriteLine($"RSA encryption:{ rsaStr}");
string dersaStr = RSAHelper.RSADecrypt(privateKey, rsaStr);
Console.WriteLine($"RSA decrypt:{ dersaStr}");

The results are shown in the figure below:

RSA encryption has a feature that it has a length limit on the encrypted string.

Length restriction rule: the number of bytes to be encrypted cannot exceed the length value of the key divided by 8 and then minus 11 (i.e. RSACryptoServiceProvider.KeySize / 8 - 11). The number of bytes of the encrypted ciphertext is exactly the length value of the key divided by 8 (i.e. RSACryptoServiceProvider.KeySize / 8). Note: this length refers to the length of byte [] array, not the length of string.

In short, the encrypted string cannot be too long.

However, in real business, the string we need to encrypt is often very long. Then, RSA has a length limit on the encrypted string. What should we do? Very simple, the string to be encrypted is disassembled, the length of each segment is less than or equal to the limit length, and then encrypted in segments. In this way, the problem is solved.

The segment encryption code is as follows:

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;  //Maximum length limit of encryption block
 
  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);
  }
 
}
/// 
 
///Segment decryption for long strings
/// 
/// 
/// 
/// 
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;  //Maximum decryption block 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());
  }
}

The results are shown in the figure below:

epilogue

Now C# the commonly used encryption algorithms are introduced. Let's talk about them vb.net tutorial Let's take a look at the same string after encryption.

It can be seen that the ciphertext length obtained by different encryption methods is different, and the ciphertext length of the mode encoded in Base64 after DES encryption is the shortest. RSA encryption has the longest ciphertext.

Source code of this article
The source code used in this article is that you have finished sorting, and you can obtain it in the following ways

Topics: C#