Mã hóa và giải mã dữ liệu bằng khóa đối xứng trong C# sử dụng thuật toán mã hóa khóa đối xứng AES

Mã hóa và giải mã dữ liệu bằng khóa đối xứng trong C# sử dụng thuật toán mã hóa khóa đối xứng AES

1. Tổng quan.

  • AES (viết tắt của từ tiếng anh: Advanced Encryption Standard, hay Tiêu chuẩn mã hóa nâng cao) là một thuật toán mã hóa khối được chính phủ Hoa Kỳ áp dụng làm tiêu chuẩn mã hóa.
  • Thuật toán được xây dựng dựa trên Rijndael Cipher phát triển bởi 2 nhà mật mã học người Bỉ: Joan Daemen và Vincent Rijmen.
  • AES làm việc với các khối dữ liệu 128bit và độ dài khóa 128bit, 192bit hoặc 256bit. Các khóa mở rộng sử dụng trong chu trình được tạo ra bởi thủ tục sinh khóa Rijndael.
  • Hầu hết các phép toán trong thuật toán AES đều thực hiện trong một trường hữu hạn của các byte. Mỗi khối dữ liệu đầu vào 128bit được chia thành 16byte, có thể xếp thành 4 cột, mỗi cột 4 phần tử hay một ma trận 4×4 của các byte, nó gọi là ma trận trạng thái.
  • Tùy thuộc vào độ dài của khóa khi sử dụng 128bit, 192bit hay 256bit mà thuật toán được thực hiện với số lần lặp khác nhau.
  • Thiết kế và độ dài khóa của thuật toán AES ( 128, 192 và 256 bit ) là đủ an toàn để bảo vệ các thông tin được xếp vào loại tối mật nhưng về an ninh của AES thì các nhà khoa học đánh giá là chưa cao. Nếu các kỹ thuật tấn công được cải thiện thì AES có thể bị phá vỡ.

2. Mã hóa và giải mã dữ liệu bằng khóa đối xứng trong C#.

Khóa đối xứng là một chuỗi được sử dụng để mã hóa dữ liệu và với cùng một chuỗi, chúng ta có thể giải mã dữ liệu, có nghĩa là cần có một chuỗi duy nhất để mã hóa và giải mã.

Mã hóa và giải mã bằng khóa đối xứng trong C #

Sau đây là đoạn mã viết bằng C# gồm 2 hàm mã hóa và giải mã sử dụng thuật toán mã hóa khóa đối xứng AES:

using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace EncryptionDecryptionUsingSymmetricKey
{
    public class AesOperation
    {
        // Hàm mã hóa dữ liệu
        public static string EncryptString(string key, string plainText)
        {
            byte[] iv = new byte[16];
            byte[] array;

            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = iv;

                ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);

                using (MemoryStream memoryStream = new MemoryStream())
                {
                    using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, encryptor, CryptoStreamMode.Write))
                    {
                        using (StreamWriter streamWriter = new StreamWriter((Stream)cryptoStream))
                        {
                            streamWriter.Write(plainText);
                        }

                        array = memoryStream.ToArray();
                    }
                }
            }

            return Convert.ToBase64String(array);
        }
        // Hàm giải mã dữ liệu
        public static string DecryptString(string key, string cipherText)
        {
            byte[] iv = new byte[16];
            byte[] buffer = Convert.FromBase64String(cipherText);

            using (Aes aes = Aes.Create())
            {
                aes.Key = Encoding.UTF8.GetBytes(key);
                aes.IV = iv;
                ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);

                using (MemoryStream memoryStream = new MemoryStream(buffer))
                {
                    using (CryptoStream cryptoStream = new CryptoStream((Stream)memoryStream, decryptor, CryptoStreamMode.Read))
                    {
                        using (StreamReader streamReader = new StreamReader((Stream)cryptoStream))
                        {
                            return streamReader.ReadToEnd();
                        }
                    }
                }
            }
        }
    }
}

Trong đoạn mã trên, tôi đã sử dụng class Aes được xác định trước nằm trong namespace System.Security.Cryptography sử dụng cùng một khóa để mã hóa và giải mã. Thuật toán AES hỗ trợ mã hóa 128, 198 và 256 bit.

Chúng ta cũng có thể thấy trong đoạn mã trên, chúng ta đã sử dụng vectơ khởi tạo (IV) có kích thước 16 byte, kích thước khối của thuật toán. IV là tùy chọn.

Bây giờ chúng ta có 1 ví dụ đơn giản sau để áp dụng đoạn mã mã hóa và giải mã trên:

using System;

namespace EncryptionDecryptionUsingSymmetricKey
{
    class Program
    {
        static void Main(string[] args)
        {
            var key = "b14ca5898a4e4133bbce2ea2315a1916"; 

            Console.WriteLine("Hãy nhập vào một chuỗi để mã hóa:");
            var str = Console.ReadLine();
            var encryptedString = AesOperation.EncryptString(key, str);
            Console.WriteLine($"Chuỗi đã mã hóa = {encryptedString}");

            var decryptedString = AesOperation.DecryptString(key, encryptedString);
            Console.WriteLine($"Chuỗi đã giải mã = {decryptedString}");

            Console.ReadKey();
        }
    }
}

Trong đoạn mã đã cho, tôi đang sử dụng một giá trị được mã hóa cứng làm khóa nhưng trong thời gian thực, tôi có thể lấy khóa trong thời gian chạy và ngoài ra tôi có thể sử dụng vectơ khởi tạo tùy chọn (IV) tùy theo độ phức tạp mà tôi cần.

Series Navigation<< Hướng dẫn đồng bộ khi tên thuộc tính JSON khác thuộc tính Class model trong JsonConvert.DeserializeObject (Chuyển chuỗi Json từ đọc API thành Class model)
Share