1. Trang chủ
  2. » Công Nghệ Thông Tin

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

10 515 5
Tài liệu đã được kiểm tra trùng lặp

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Bảo đảm tính toàn vẹn dữ liệu bằng mã băm có khóa
Chuyên ngành Mật mã
Định dạng
Số trang 10
Dung lượng 185,06 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

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ượn

Trang 1

1.1 Bảo đảm tính toàn vẹn dữ liệu bằng mã băm có khóa

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ừ 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 (đã được

thảo luận trong mục 14.2 và 14.3); 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 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 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 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

Trang 2

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 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 mã băm có khóa Bảng 14.2 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) {

// 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

Trang 3

// được chỉ định trong đối số dòng lệnh thứ nhất)

using (Stream file = new FileStream(args[0],

FileMode.Open)) {

// Tạo mã băm có khóa cho nội dung file

byte[] hash = hashAlg.ComputeHash(file);

// Hiển thị mã 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 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

1.2 Bảo vệ file bằng phép mật hóa đối xứng

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

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

Trang 4

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 mã lệnh đượ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) 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 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 đố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

Trang 5

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

Trang 6

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;

Trang 7

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

Trang 8

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

Trang 9

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

Trang 10

destFile.Close(); }

}

}

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

HÌNH ẢNH LIÊN QUAN

Bảng 14.3 Các hiện thực giải thuật đối xứng - Tài liệu Mật mã ( Cryptography) phần 2 pdf
Bảng 14.3 Các hiện thực giải thuật đối xứng (Trang 4)
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 (Trang 6)

TỪ KHÓA LIÊN QUAN

w