Bạn cần chuyển một file cho ai đó và cấp cho người này một phương cách để xác minh tính toàn vẹn của file. Cách thực là cấp cho người nhận một khóa bí mật (key). Khóa này có thể là một số được sinh ngẫu nhiên, nhưng nó cũng có thể là một nhóm từ mà bạn và người nhận đã thỏa thuận.
Sử dụng khóa cùng với một trong những lớp giải thuật băm có khóa dẫn xuất từ lớp System.Security.Cryptography.KeyedHashAlgorithm để tạo mã băm có khóa. Gửi mã băm này cùng với file. Khi nhận được file, người nhận sẽ tạo mã băm có khóa cho file này bằng khóa. Nếu hai mã băm giống nhau, người nhận sẽ biết rằng file này do bạn gửi đến và nó không bị thay đổi trong quá trình chuyển giao.
Mã băm rất hữu ích khi so sánh hai mẩu dữ liệu để xác định chúng có giống nhau hay không (cả khi bạn không thể truy xuất được dữ liệu gốc). Tuy nhiên, bạn không thể sử dụng mã băm để cam đoan với người nhận về tính toàn vẹn của dữ liệu. Nếu có ai đó chặn được dữ liệu, người này có thể thay thế dữ liệu và tạo mã băm mới. Khi người nhận kiểm tra mã băm, nó có vẻ đúng nhưng thực tế dữ liệu không giống với những gì bạn gửi lúc ban đầu.
Một giải pháp đơn giản và hiệu quả cho vấn đề toàn vẹn dữ liệu là mã băm có khóa ( keyed hash code). Mã băm có khóa cũng tương tự như mã băm bình thường; tuy nhiên, mã băm có khóa kết hợp thêm một phần tử dữ liệu bí mật (khóa), phần tử này chỉ có người gửi và người nhận biết. Nếu không có khóa, không ai có thể tạo được mã băm đúng từ tập dữ liệu cho trước.
Khóa phải được giữ bí mật. Nếu ai đó biết khóa thì có thể tạo ra mã băm có khóa hợp lệ, nghĩa là bạn sẽ không thể xác định họ có thay đổi nội dung của tài liệu hay không. Vì lý do này, bạn không nên chuyển giao hay lưu trữ khóa cùng với tài liệu cần được bảo vệ tính toàn vẹn.
Tạo mã băm có khóa cũng tương tự như tạo mã băm bình thường vì lớp trừu tượng System.Security.Cryptography.KeyedHashAlgorithm mở rộng lớp System.Security.Cryptography.HashAlgorithm. Lớp KeyedHashAlgorithm cung cấp một lớp cơ sở để tất cả các giải thuật băm có khóa dẫn xuất từ đó. Thư viện lớp .NET Framework có hai hiện thực giải thuật băm có khóa được liệt kê trong bảng sau; mỗi hiện thực là một thành viên của không gian tên System.Security.Cryptography.
Giải thuật/Tên lớp |
Kích thước khóa (bit) |
Kích thước mã băm (bit) |
HMACSHA1 |
bất kỳ |
160 |
MACTripleDES |
64, 128, 192 |
64 |
Cũng như các giải thuật băm chuẩn, bạn có thể trực tiếp tạo ra các đối tượng giải thuật băm có khóa, hoặc bạn có thể sử dụng phương thức tĩnh KeyedHashAlgorithm.Create với đối số là tên giải thuật. Sử dụng factory cho phép bạn viết mã lệnh tổng quát và mã lệnh này có thể làm việc với bất kỳ hiện thực giải thuật băm có khóa nào, nhưng theo bảng trên, mỗi lớp hỗ trợ các chiều dài khóa khác nhau nên bạn phải cung cấp giá trị này trong mã lệnh tổng quát.
Nếu sử dụng phương thức khởi dựng để tạo đối tượng băm có khóa, bạn có thể truyền khóa cho phương thức này. Khi sử dụng factory, bạn phải thiết lập khóa bằng thuộc tính Key (được thừa kế từ lớp KeyedHashAlgorithm). Một khi đã cấu hình khóa, gọi phương thức ComputeHash với đối số là một mảng byte hay một đối tượng System.IO.Stream. Giải thuật băm có khóa sẽ xử lý dữ liệu nhập và trả về một mảng byte chứa mã băm có khóa. Bảng trên cho thấy kích thước của mã băm do mỗi giải thuật băm có khóa sinh ra.
Lớp KeyedHashStreamExample dưới đây trình bày cách tạo mã băm có khóa từ một file. Bạn phải chỉ định tên file và một khóa làm đối số dòng lệnh. Ứng dụng này sử dụng lớp HMACSHA1 để tạo mã băm có khóa và rồi hiển thị nó ra cửa sổ Console.
- using System; using System.IO; using System.Text;
- using System.Security.Cryptography;
- public class KeyedHashStreamExample {
- public static void Main(string[] args) {
-
- byte[] key = Encoding.Unicode.GetBytes(args[1]);
-
-
- using (HMACSHA1 hashAlg = new HMACSHA1(key)) {
-
-
- using (Stream file = new FileStream(args[0],FileMode.Open)) {
-
- byte[] hash = hashAlg.ComputeHash(file);
-
- Console.WriteLine(BitConverter.ToString(hash));
- }
- }
- }
- }
Lệnh
- KeyedHashStreamExample KeyedHashStreamExample.cs secretKey
sẽ sinh ra mã băm như sau:
95-95-2A-8E-44-D4-3C-55-6F-DA-06-44-27-79-29-81-15-C7-2A-48
Ứng dụng KeyedHashMessageExample.cs trình bày cách tạo một mã băm có khóa từ một chuỗi. Ứng dụng này yêu cần hai đối số dòng lệnh: một thông điệp và một khóa, và sẽ tạo ra mã băm có khóa cho chuỗi thông điệp bằng khóa này. Ví dụ, lệnh
-
KeyedHashMessageExample "Two hundred dollars is my final offer" secretKey
sẽ sinh ra mã băm như sau:
83-43-0D-9D-07-6F-AA-B7-BC-79-CD-6F-AD-7B-FA-EA-19-D1-24-44
[sưu tầm]