.NET Cryptography & Mã hóa dữ liệu

Màu nền
Font chữ
Font size
Chiều cao dòng

.NET Cryptography & Mã hóa dữ liệu

Posted on 14/10/2011 by Khoa Pham

Ngày nay, mã hóa dữ liệu đã trở nên một nhu cầu phổ biến. Trong rất nhiều tình huống (lưu trữ password, gửi thông tin qua mạng…) chúng ta sẽ cần đến mã hóa để bảo vệ thông tin nhạy cảm khỏi những cặp mắt tò mò. Có lẽ chính Microsoft cũng nhận thức được vấn đề này nên trong .NET Framework có hẳn một namespace System.Security.Cryptography phục vụ cho việc mã hóa dữ liệu. Nhưng trước tiên, chúng ta hãy cùng xem qua một vài khái niệm mã hóa cơ bản:

PUBLIC-KEY ENCRYPTION:

Còn gọi là mã hóa bất đối xứng (asymmetric encryption), sử dụng một cặp khóa để mã hóa/giải mã, trong đó khóa public được công khai cho mọi người và khóa private được giữ bí mật. Thông thường, khóa public sẽ được dùng để mã hóa, và chỉ những ai có khóa private mới có thể giải mã. Tuy nhiên cũng có những trường hợp ngược lại: mã hóa bằng khóa private và giải mã bằng khóa public. Trường hợp này được ứng dụng trong chữ ký điện tử, giúp chứng thực người gửi và đảm bảo thông tin đã không bị thay đổi trong quá trình truyền đi (nếu thông tin bị thay đổi sau khi đã mã hóa bằng khóa private thì sẽ không thể giải mã bằng khóa public được nữa). Các giải thuật mã hóa bất đối xứng thông dụng gồm:

• RSA

• DSA (Digital Signature Algorithm)

PRIVATE-KEY ENCRYPTION:

Còn gọi là mã hóa đối xứng, chỉ sử dụng một khóa duy nhất để mã hóa và giải mã thông tin. Kiểu mã hóa này còn có một cái tên khác là mã hóa khối (block cipher) vì dữ liệu thường được mã hóa theo từng khối. Để tăng tính an toàn, .NET sử dụng một kĩ thuật gọi là chaining, trong đó thông tin từ các khối trước được sử dụng để mã hóa các khối tiếp theo, khiến cho khóa mã không thể bị suy ra ngay cả khi biết được cấu trúc dữ liệu. Các giải thuật mã hóa đối xứng thông dụng gồm:

• RC2

• DES, Tripple DES

• Rijndael

CÁC GIẢI THUẬT BĂM:

Các giải thuật băm phổ biến gồm MD5 và SHA1, đây là các giải thuật mã hóa một chiều. Dữ liệu sau khi mã hóa luôn có kích thước cố định và không thể khôi phục lại được nữa. Các giải thuật này cũng đảm bảo sẽ cho ra những kết quả khác nhau nếu dữ liệu đầu vào khác nhau và ngược lại.

LỰA CHỌN GIẢI THUẬT NÀO CHO PHÙ HỢP?

Nhìn chung, các giải thuật mã hóa đối xứng cho tốc độ rất nhanh và phù hợp khi cần mã hóa một lượng lớn dữ liệu. Tuy nhiên, khóa mã hóa là một chuỗi kí tự với chiều dài cố định và có thể bị bẻ khóa nếu có đủ thời gian (bằng các phương pháp đơn giản như vét cạn). Ngược lại, các giải thuật mã hóa bất đối xứng chậm hơn nhưng tương đối an toàn hơn (vì cần đến cả hai khóa public và private). Một kịch bản phổ biến trong trường hợp cần mã hóa thông tin khối lượng lớn là mã hóa thông tin này bằng một giải thuật đối xứng, và sử dụng giải thuật bất đối xứng để mã hóa khóa của giải thuật đối xứng đó (khi mã hóa đối xứng, khóa mã cần được gửi đi kèm với thông tin đã mã hóa để bên nhận có thể giải mã. Việc mã hóa khóa này giúp đảm bảo an toàn. Khi đó bên nhận sẽ sử dụng private key của mình để giải mã khóa mã, rồi dùng khóa mã này giải mã thông tin cần nhận)

Các giải thuật băm thường áp dụng cho các khối dữ liệu nhỏ như password. Vì là mã hóa một chiều, thông tin sẽ không thể đọc được đối với cả người quản trị hệ thống hay trong trường hợp cơ sở dữ liệu bị chiếm dụng, giúp tăng độ an toàn. Trong trường hợp password, chỉ có phiên bản đã băm của password được lưu trữ. Khi user login, chuỗi password do user nhập vào sẽ được băm lại một lần nữa bằng cùng một giải thuật băm, sau đó hai chuỗi băm được so sánh để xác định kết quả.

HIỆN THỰC:

Đoạn code sau minh họa cách mã hóa một chuỗi kí tự trong C# sử dụng giải thuật mã hóa đối xứng Rijndael:

public string Encode(string source)

{

byte[] binarySource = Encoding.UTF8.GetBytes(source);

System.Security.Cryptography.SymmetricAlgorithm rijn =    System.Security.Cryptography.SymmetricAlgorithm.Create();

MemoryStream ms = new MemoryStream();

byte[] rgbIV = Encoding.ASCII.GetBytes("initialization vector");

byte[] key = Encoding.ASCII.GetBytes("key to encrypt/decrypt data");

CryptoStream cs = new CryptoStream(ms, rijn.CreateEncryptor(key, rgbIV),  CryptoStreamMode.Write);

cs.Write(binarySource, 0, binarySource.Length);

cs.Close();

return Convert.ToBase64String(ms.ToArray());

}

Đoạn code trên sử dụng phương thức Create() của lớp SymmetricAlgorithm để tạo một đối tượng cryptographic dùng cho mã hóa. SymmetricAlgorithm là lớp abstract và là lớp cha của tất cả các giải thuật mã hóa đối xứng trong .NET Framework. SymmetricAlgorithm không thể được khởi tạo trực tiếp (vì là abstract) nhưng cung cấp phương thức static Create(). Phương thức này dùng để khởi tạo đối tượng của một lớp giải thuật kế thừa từ SymmetricAlgorithm và có hai phiên bản: một phiên bản không nhận tham số (mặc định khởi tạo một đối tượng giải thuật Rijndael) và một phiên bản có nhận tham số cho phép xác định tên giải thuật cần khởi tạo đối tượng. Như đã đề cập, Rijndael sử dụng kĩ thuật chaining để bảo vệ khóa mã. Kĩ thuật này yêu cầu cung cấp một vector khởi tạo. Vector đó được thể hiện bởi biến rgbIV. Key là khóa để mã hóa dữ liệu. Dữ liệu sau khi mã hóa lại được trả về ở dạng chuỗi (đương nhiên là không thể đọc được nữa!). Cuối cùng, phương thức Decode() cho phép khôi phục dữ liệu về trạng thái ban đầu (lưu ý là hai tham số rgbIV và key của hai phương thức phải giống nhau):

private string Decode(string source)

{

byte[] binarySource = Convert.FromBase64String(source);

MemoryStream ms = new MemoryStream();

System.Security.Cryptography.SymmetricAlgorithm rijn =   System.Security.Cryptography.SymmetricAlgorithm.Create();

byte[] rgbIV = Encoding.ASCII.GetBytes("initialization vector");

byte[] key = Encoding.ASCII.GetBytes("key to encrypt/decrypt data");

CryptoStream cs = new CryptoStream(ms, rijn.CreateDecryptor(key, rgbIV),

CryptoStreamMode.Write);

cs.Write(binarySource, 0, binarySource.Length);

cs.Close();

return Encoding.UTF8.GetString(ms.ToArray());

}

Pasted from <http://www.toiyeucongnghe.com/index.php/2011/10/net-cryptography-ma-hoa-du-lieu/> 

Bạn đang đọc truyện trên: Truyen2U.Pro