Tài liệu Mật mã ( Cryptography) phần 2 pdf

10 513 5
Tài liệu Mật mã ( Cryptography) phần 2 pdf

Đang tải... (xem toàn văn)

Thông tin tài liệu

1.1 Bảo đảm tính toàn vẹn dữ liệu bằng băm có khóa V V 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ấ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ừ 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 băm có khóa. Gửi băm này cùng với file. Khi nhận được file, người nhận sẽ tạo băm có khóa cho file này b ằng khóa. Nếu hai 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 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 băm mới. Khi người nhận kiểm tra 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 băm có khóa (keyed hash code). băm có khóa cũng tương tự như b ăm bình thường (đã được thảo luận trong mục 14.2 và 14.3); tuy nhiên, băm có khóa kết hợp thêm một phần tử dữ liệumậ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 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 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. Mục 14.10 sẽ cung cấp một cơ chế mà bạn có thể sử dụng để trao đổi khóa một cách an toàn. Tạo bă m có khóa cũng tương tự như tạo 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 14.2; mỗi hiện thực là một thành viên của không gian tên System.Security.Cryptography. Bả ng 14.2 Các hiện thực giải thuật băm có khóa Giải thuật/Tên lớp Kích thước khóa (bit) Kích thước 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 lệnh tổng quát và 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 14.2, 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 băm có khóa. Bảng 14.2 cho thấy kích thước của 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 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 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) { // Tạo mảng byte từ chuỗi key (là đối số dòng lệnh thứ hai). byte[] key = Encoding.Unicode.GetBytes(args[1]); // Tạo một đối tượng HMACSHA1 // (truyền key cho phương thức khởi dựng). using (HMACSHA1 hashAlg = new HMACSHA1(key)) { // Mở một FileStream để đọc file (tên file // được chỉ định trong đối số dòng lệnh thứ nhất). using (Stream file = new FileStream(args[0], FileMode.Open)) { // Tạo băm có khóa cho nội dung file. byte[] hash = hashAlg.ComputeHash(file); // Hiển thị băm có khóa ra cửa sổ Console. 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 (có trong đĩa CD đính kèm) trình bày cách tạo một 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 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 băm như sau: 83-43-0D-9D-07-6F-AA-B7-BC-79-CD-6F-AD-7B-FA-EA-19-D1-24-44 1.2 Bảo vệ file bằng phép mật hóa đối xứng V V Bạn cần mật hóa một file bằng giải thuật mật hóa đối xứng (symmetric encryption). # # Trước hết, bạn phải thể hiện hóa một trong các lớp giải thuật đối xứng cụ thể dẫn xuất từ lớp System.Security.Cryptography.SymmetricAlgorithm. Sau đó, gọi phương thức CreateEncryptor hay CreateDecryptor của đối tượng SymmetricAlgorithm để thu lấy một đối tượng có hiện thực giao diện System.Security.Cryptography.ICryptoTransform. Sử dụng đối tượng ICryptoTransform này kết hợp với một đối tượng System.Security.Cryptography.CryptoStream để mật hóa hay giải mật hóa d ữ liệu đọc từ một file (được truy xuất bằng một đối tượng System.IO.FileStream). Lớp trừu tượng SymmetricAlgorithm cung cấp một lớp cơ sở để tất cả các hiện thực giải thuật đối xứng cụ thể dẫn xuất từ đó. Thư viện lớp .NET Framework có bốn hiện thực giải thuật đối xứng cụ thể được liệ t kê trong bảng 14.3, mỗi lớp là một thành viên của không gian tên System.Security.Cryptography. Các lớp có đuôi là CryptoServiceProvider bọc lấy các chức năng do Win32 CryptoAPI cung cấp, trong khi các lớp có đuôi là Managed (hiện tại chỉ có RijndaelManaged) được hiện thực hoàn toàn bằng lệnh được-quản-lý. Bảng này cũng cho thấy chiều dài khóa mỗi giải thuật hỗ trợ (chiều dài mặc định được in đậm). Nói chung, khóa càng dài, càng khó giải mật hóa ciphertext nếu không có khóa, nhưng cũng có nhiều yếu tố khác cần xem xét. Bảng 14.3 Các hiện thực giải thuật đố i xứng Tên giải thuật Tên lớp Chiều dài khóa (bit) DES DESCryptoServiceProvider 64 TripleDES hay 3DES TripleDESCryptoServiceProvider 128, 192 RC2 RC2CryptoServiceProvider 40, 48 56, 64, 72, 80, 88, 96, 104, 112, 120, 128 Rijndael RijndaelManaged 128, 192, 256 Mặc dù bạn có thể tạo ra các thể hiện của các lớp giải thuật đối xứng một cách trực tiếp, lớp cơ sở SymmetricAlgorithm là một factory cho các lớp hiện thực cụ thể dẫn xuất từ đó. Gọi phương thức tĩnh SymmetricAlgorithm.Create với đối số là tên giải thuật sẽ trả về một đối tượng thuộc kiểu đã được chỉ định. Sử dụng factory cho phép bạn viết lệnh tổng quát, và lệnh này có thể làm việc với bất kỳ hiện thực giải thuật đối xứng nào: string algName = "3DES"; SymmetricAlgorithm alg = SymmetricAlgorithm.Create(algName); # Nếu bạn gọi SymmetricAlgorithm.Create và không chỉ định tên giải thuật, SymmetricAlgorithm sẽ trả về một đối tượng RijndaelManaged. Nếu bạn chỉ định một giá trị không hợp lệ, SymmetricAlgorithm sẽ trả về null. Bạn có thể cấu hình các ánh xạ tên/lớp mới bằng file cấu hình (xem tài liệu .NET Framework SDK để biết thêm chi tiết). Trước khi mật hóa dữ liệu với một trong các lớp giải thuật đối xứng, b ạn cần một khóa (key) và một vectơ khởi động (initialization vector). Khóa là thông tin bí mật dùng để mật hóa và giải mật hóa dữ liệu. Vectơ khởi động là dữ liệu ngẫu nhiên được truyền cho giải thuật mật hóa. Bạn phải sử dụng cùng khóa và vectơ khởi động cho cả mật hóa và giải mật hóa dữ liệu. Tuy nhiên, chỉ có khóa là cần phải được giữ bí mật, bạn có thể lư u trữ hay gửi vectơ khởi động cùng với dữ liệu đã-được-mật-hóa. Khóa cho mỗi lớp dẫn xuất từ SymmetricAlgorithm có thể được truy xuất thông qua thuộc tính Key, và vectơ khởi động có thể được truy xuất thông qua thuộc tính IV. Cách đơn giản nhất và ít lỗi nhất để tạo khóa và vectơ khởi động mới là để lớp tự tạo chúng giùm bạn. Sau khi đã tạo một đối tượng giải thuật đối xứng, nếu bạn không thiết lập các thuộc tính Key và IV cho nó, đối tượng này sẽ tự động tạo ra các giá trị mới ngay khi bạn cho gọi một thành viên có sử dụng các giá trị Key và IV. Một khi đã được thiết lập, đối tượng giải thuật đối xứng sẽ tiếp tục sử dụng các giá trị Key và IV này. Để thay đổi giá trị của Key và IV, bạn có thể gán trực tiếp các giá trị mới hoặc gọi phương thức GenerateKey và GenerateIV (buộc đối tượng giải thuật đối x ứng tạo ra các giá trị ngẫu nhiên mới). Bạn không thể trực tiếp thực hiện mật hóa và giải mật hóa với một đối tượng giải thuật đối xứng. Một khi đã tạo và cấu hình đối tượng giải thuật đối xứng, bạn phải gọi phương thức CreateEncryptor hay CreateDecryptor của nó để thu lấy một đối tượng có hiện thực giao diện System.Security.Cryptography.ICryptoTransform. Kế đ ó, bạn có thể sử dụng các phương thức của đối tượng ICryptoTransform này để mật hóa và giải mật hóa dữ liệu. Tuy nhiên, đối tượng ICryptoTransform yêu cầu bạn truyền dữ liệu theo từng khối (có kích thước cố định) và lấp (bằng tay) khối dữ liệu cuối cùng vì khối này ít khi có kích thước đúng. Giao diện ICryptoTransform không quá khó sử dụng, nhưng không mấy thân thiện; do vậy .NET Framework kèm thêm lớp System.Security.Cryptography.CryptoStream. Đây là l ớp dẫn xuất từ System.IO.Stream, dùng để đơn giản hóa việc mật hóa và giải mật hóa dữ liệu được đọc từ các đối tượng Stream khác. Lớp này cho phép bạn mật hóa và giải mật hóa dữ liệu từ các file và các kết nối mạng một cách dễ dàng bằng một mô hình xử lý quen thuộc, và nó cung cấp cho bạn tất cả các tiện ích quen thuộc khi truy xuất dữ liệu dựa-vào-Stream. Phương thức khởi d ựng của CryptoStream yêu cầu ba đối số: một Stream nằm dưới, một thể hiện của ICryptoTransform, và một giá trị thuộc kiểu liệt kê System.Security.Cryptography.CryptoStreamMode. Giá trị CryptoStreamMode cho biết chế độ của đối tượng CryptoStream mới; các giá trị hợp lệ là Read và Write. Khi bạn gọi phương thức Read hay Write của CryptoStream, CryptoStream sẽ sử dụng thể hiện ICryptoTransform để mật hóa và giải mật hóa dữ liệu đang truyền qua CryptoStream. Đối tượ ng CryptoStream bảo đảm kích thước khối dùng cho thể hiện ICryptoTransform luôn đúng. Cấu hình của một đối tượng CryptoStream có tính linh hoạt cao, nhưng có thể hơi khó hiểu. Bảng 14.4 mô tả hoạt động của một đối tượng CryptoStream dựa trên chế độ của CryptoStream và kiểu thể hiện ICryptoTransform được sử dụng trong phương thức khởi dựng của CryptoStream. Bảng 14.4 Hoạt động của đối tượng CryptoStream Chế độ của CryptoStream Chỉ thị của ICryptoTransform Mô tả Read Mật hóa Stream nằm dưới chứa plaintext nguồn. CryptoStream.Read ghi ciphertext ra bộ đệm xuất. Read Giải mật hóa Stream nằm dưới chứa ciphertext nguồn. CryptoStream.Read ghi plaintext ra bộ đệm xuất. Write Mật hóa CryptoStream.Write chỉ định plaintext cần mật hóa. Stream nằm dưới nhận ciphertext đã-được-mật-hóa. Write Giải mật hóa CryptoStream.Write chỉ định ciphertext cần giải mật hóa. Stream nằm dưới nhận plaintext đã-được-giải-mật-hóa. Lớp SymmetricEncryptionExample dưới đây trình bày cách sử dụng giải thuật Triple DES để mật hóa một file và rồi giải mật hóa file đó. Phương thức Main nhận tên của file cần mật hóa làm đối số dòng lệnh. Trước tiên, nó sẽ tạo khóa và vectơ khởi động; sau đó, gọi phương thức EncryptFile, kế tiếp là phương thức DecryptFile, và sinh ra hai file: file thứ nhất chứa phiên bản đã-được-mật-hóa của file nguồn, file thứ hai ch ứa phiên bản đã- được-giải-mật-hóa của file đã-được-mật-hóa (giống file nguồn). using System; using System.IO; using System.Security.Cryptography; public class SymmetricEncryptionExample { public static void Main(string[] args) { // Tạo một giải thuật Triple DES mới để thu lấy khóa dùng cho // ví dụ này. Khóa này sẽ được dùng chung trong các phương thức // EncryptFile và DecryptFile. Bình thường, khóa được // thỏa thuận giữa người gửi và người nhận, hoặc được gửi // (bởi người gửi) cùng với file đã-được-mật-hóa. byte[] key; byte[] iv; using(SymmetricAlgorithm alg = SymmetricAlgorithm.Create("3DES")){ key = alg.Key; iv = alg.IV; } // Mật hóa file. Tiền tố "encrypted" sẽ được thêm vào tên file // nguồn và được sử dụng làm tên của file đã-được-mật-hóa. EncryptFile(args[0], "encrypted"+args[0], (byte[])key.Clone(), (byte[])iv.Clone()); // Giải mật hóa file đã-được-mật-hóa. Tiền tố "decrypted" sẽ được // thêm vào tên file gốc và được sử dụng làm tên của file // đã-được-giải-mật-hóa. DecryptFile("encrypted"+args[0], "decrypted"+args[0], key, iv); } // Phương thức dùng để mật hóa một file (bằng giải thuật Triple DES) // với key và iv cho trước. private static void EncryptFile(string srcFileName, string destFileName, byte[] key, byte[] iv) { // Tạo các stream để truy xuất file ngu ồn và file đích. Stream srcFile = new FileStream(srcFileName, FileMode.Open, FileAccess.Read); Stream destFile = new FileStream(destFileName, FileMode.Create, FileAccess.Write); // Tạo một giải thuật Triple DES mới để mật hóa file. using(SymmetricAlgorithm alg = SymmetricAlgorithm.Create("3DES")){ // Cấu hình thuộc tính Key và IV của giải thuật. alg.Key = key; alg.IV = iv; // Tạo một CryptoStream để mật hóa nội dung của // Stream nguồn khi nó được đọc. Gọi phương thức // CreateEncryptor của SymmetricAlgorithm // để nhận thể hiện ICryptoTransform và // truyền nó cho CryptoStream. CryptoStream cryptoStream = new CryptoStream(srcFile, alg.CreateEncryptor(), CryptoStreamMode.Read); // Khai báo bộ đệm dùng để đọc dữ liệu từ file nguồn // thông qua CryptoStream và ghi nó ra file đích. int bufferLength; byte[] buffer = new byte[1024]; // Đọc file nguồn (từng khối 1024 byte) và ghi phiên bản // đã-được-mật-hóa ra file đích. do { bufferLength = cryptoStream.Read(buffer, 0, 1024); destFile.Write(buffer, 0, bufferLength); } while (bufferLength > 0); // Đóng stream và xóa các dữ liệu bí mật. destFile.Flush(); Array.Clear(key,0,key.Length); Array.Clear(iv,0,iv.Length); cryptoStream.Clear(); cryptoStream.Close(); srcFile.Close(); destFile.Close(); } } // Phương thức dùng để giải mật hóa một file đã-được-mậ t-hóa bằng // giải thuật Triple DES với key và iv cho trước. private static void DecryptFile(string srcFileName, string destFileName, byte[] key, byte[] iv) { // Tạo các stream để truy xuất file nguồn và file đích. Stream srcFile = new FileStream(srcFileName, FileMode.Open, FileAccess.Read); Stream destFile = new FileStream(destFileName, FileMode.Create, FileAccess.Write); // Tạo một giải thuật Triple DES mới để giải mật hóa file. using(SymmetricAlgorithm alg = SymmetricAlgorithm.Create("3DES")){ // Cấu hình thuộc tính Key và IV của giải thuật. alg.Key = key; alg.IV = iv; // Tạo một CryptoStream để giải mật hóa nội dung của dữ liệu // đã-được-mật-hóa khi nó được ghi. Gọi phương thức // CreateDecryptor của SymmetricAlgorithm để nhận thể hiện // ICryptoTransform và truyền nó cho CryptoStream. CryptoStream cryptoStream = new CryptoStream(destFile, alg.CreateDecryptor(), CryptoStreamMode.Write); // Khai báo bộ đệm dùng để đọc dữ liệu từ file đã-được- // mậ t-hóa và ghi ra file đích thông qua CryptoStream. int bufferLength; byte[] buffer = new byte[1024]; // Đọc file đã-được-mật-hóa (từng khối 1024 byte) và ghi // phiên bản đã-được-giải-mật-hóa ra file đích. do { bufferLength = srcFile.Read(buffer, 0, 1024); cryptoStream.Write(buffer, 0, bufferLength); } while (bufferLength > 0); // Đóng stream và xóa các dữ liệu bí mật. cryptoStream.FlushFinalBlock(); Array.Clear(key,0,key.Length); Array.Clear(iv,0,iv.Length); cryptoStream.Clear(); cryptoStream.Close(); srcFile.Close(); destFile.Close(); } } } . 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 ( ã được thảo luận trong mục 14 .2 và 14.3); tuy nhiên, mã băm. RC2CryptoServiceProvider 40, 48 56, 64, 72, 80, 88, 96, 104, 1 12, 120 , 128 Rijndael RijndaelManaged 128 , 1 92, 25 6 Mặc dù bạn có thể tạo ra các thể

Ngày đăng: 26/01/2014, 04:20

Hình ảnh liên quan

được-quản-lý. Bảng này cũng cho thấy chiều dài khóa mà mỗi giải thuật hỗ trợ (chiều dài mặc định được in đậm) - Tài liệu Mật mã ( Cryptography) phần 2 pdf

c.

quản-lý. Bảng này cũng cho thấy chiều dài khóa mà mỗi giải thuật hỗ trợ (chiều dài mặc định được in đậm) Xem tại trang 4 của tài liệu.
Bảng 14.4 Hoạt động của đối tượng CryptoStream - Tài liệu Mật mã ( Cryptography) phần 2 pdf

Bảng 14.4.

Hoạt động của đối tượng CryptoStream Xem tại trang 6 của tài liệu.

Tài liệu cùng người dùng

Tài liệu liên quan