Tải bản đầy đủ (.pdf) (9 trang)

Mật mã ( Cryptography) phần 3

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (192.97 KB, 9 trang )

1.1
Truy lại khóa đối xứng từ password
V
V


Bạn cần tạo một khóa đối xứng từ một password để người dùng chỉ cần nhớ
password và không cần lưu trữ khóa.
#
#


Sử dụng lớp System.Security.Cryptography.PasswordDeriveBytes để tạo khóa
đối xứng từ chuỗi password.
Hiếm có người nào nhớ được giá trị của một khóa đối xứng, và không thực tế khi bắt
người dùng nhập các số dài như thế bằng tay. Điều này nghĩa là khóa phải được lưu trữ ở
một dạng an toàn sao cho ứng dụng có thể truy xuất được (trong smart card, đĩa mềm, cơ
sở dữ liệ
u hay file). Vấn đề liên quan với việc cấp, phân bổ, truy xuất, và lưu trữ khóa là
một trong những mặt khó nhất trong quá trình hiện thực bất kỳ giải pháp mật mã nào (vấn
đề này được quy chung về quản lý khóa). Khi cần ghi nhớ một bí mật (khóa), bạn không
chỉ lo bảo vệ dữ liệu mà còn phải lo bảo vệ các bí mật dùng để bảo vệ dữ liệu!
Một cách lưu trữ khóa là cấp cho người dùng m
ột password dễ nhớ hơn và sử dụng một
giao thức truy lại khóa (key derivation protocol) để tạo một khóa đối xứng từ password.
Theo đó, mỗi khi cần mật hóa hay giải mật hóa dữ liệu, người dùng chỉ cần nhập
password và máy tính sẽ tạo ra khóa (nếu người dùng nhập cùng password, giao thức này
sẽ tạo ra cùng khóa).
#
Truy lại khóa từ những từ hay nhóm từ dễ nhớ làm giảm đáng kể tính ngẫu
nhiên của khóa, dẫn đến giảm tính bảo mật được cấp bởi những hàm mật mã


có sử dụng khóa đó. Trong trường hợp tồi tệ nhất, hacker có thể đoán được
password, và crack dữ liệu của bạn thông qua việc giải mã mật mã
(cryptanalysis).
Thư viện lớp .NET Framework có một hiện thự
c truy lại khóa đối xứng:
PasswordDeriveBytes. Lớp này sử dụng một giải thuật băm được áp dụng lặp đi lặp lại
cho một password để tạo ra một khóa với chiều dài như mong muốn. Khi cấu hình một
đối tượng PasswordDeriveBytes, bạn có thể chỉ định tên giải thuật băm cũng như số lần
lặp (mặc định, SHA-1 được áp dụng 100 lần). Ngoài ra, bạn cũng cầ
n cung cấp giá trị
salt. Salt là dữ liệu ngẫu nhiên mà quá trình truy lại khóa sẽ sử dụng để làm cho khóa tìm
được trở nên bền vững hơn đối với các dạng tấn công bằng mật mã. Bạn không cần giữ bí
mật cho giá trị salt; bạn phải lưu trữ và sử dụng nó khi truy lại khóa từ password sau này
(nếu không có giá trị salt đúng, bạn sẽ không thể truy lại khóa đúng và không thể giải mật
hóa được).
#
Bạn không thể tạo khóa bất đối xứng bằng giao thức truy lại khóa. Giải thuật
mật hóa bất đối xứng (asymmetric encryption) dựa vào các mối liên hệ toán cụ
thể giữa các thành phần khóa công khai (public key) và khóa riêng (private key).
Như thế, mỗi giải thuật mật hóa bất đối xứng yêu cầu bạn phải tuân theo một
quy trình riêng để có thể tạo ra các khóa mới.
Ví dụ dưới đây trình bày cách sử dụng lớp PasswordDeriveBytes để tạo một khóa đối
xứng gồm 64 bit từ một chuỗi password. Ví dụ này yêu cầu hai đối số dòng lệnh: tên giải
thuật băm và password (tên của các giải thuật băm đã được liệt kê trong bảng 14.1).
using System;
using System;
using System.Security.Cryptography;

public class DerivedKeyExample {


public static void Main(string[] args) {

// Sử dụng một bộ tạo số ngẫu nhiên để tạo giá trị salt.
byte[] salt = new byte[8];
RandomNumberGenerator.Create().GetBytes(salt);

// Tạo một đối tượng PasswordDeriveBytes để tạo khóa từ
// password. Cần cung cấp password nguồn (là đối số dòng
// lệnh thứ hai) và salt.
PasswordDeriveBytes pdb =
new PasswordDeriveBytes(args[1], salt);

// Thiết lập giải thuật băm dùng để tạo khóa, tên
// giải thuật được chỉ định trong đối số dòng lệnh thứ nhất.
// Giải thuật được sử dụng mặc định là SHA-1.
pdb.HashName = args[0];

// Thiết lập số lần lặp là 200 (đây là số lần giả
i thuật băm
// được áp dụng cho password để tạo khóa). Mặc định là 100.
pdb.IterationCount = 200;

// Tạo một khóa gồm 8 byte (64 bit) từ password.
// Chiều dài của khóa bị giới hạn bởi chiều dài của
// mã băm - 160 bit đối với SHA-1.
byte[] key = pdb.GetBytes(8);

// Hiển thị khóa và salt.
Console.WriteLine("Key = {0}", BitConverter.ToString(key));
Console.WriteLine("Salt = {0}", BitConverter.ToString(salt));

}
}
Chạy lệnh DerivedKeyExample SHA1 S0meVereeStr@ngeP@$$w0rd (sử dụng giải
thuật băm SHA-1 để truy lại một khóa gồm 8 byte từ chuỗi
"S0meVereeStr@ngeP@$$w0rd") sẽ sinh ra kết xuất tương tự như sau:
Key = 53-72-74-5B-A4-88-A4-80
Salt = 70-82-79-F4-3B-F9-DF-D2
Chú ý rằng, mỗi khi bạn chạy cùng một lệnh, DerivedKeyExample sinh ra khóa khác
nhau. Đó là do tác dụng của salt. Nếu bạn bỏ đi dòng lệnh gán một giá trị ngẫu nhiên vào
salt (được in đậm trong đoạn mã trên), sau đó biên dịch lại và chạy DerivedKeyExample,
bạn sẽ nhận thấy ví dụ này luôn tạo ra cùng một khóa với một password cho trước.
1.2
Gửi một bí mật bằng phép mật hóa bất đối xứng
V
V


Bạn cần sử dụng phép mật hóa bất đối xứng (asymmetric encryption) để gửi một
bí mật.
#
#


Thể hiện hóa lớp giải thuật bất đối xứng System.Security.Cryptography.
RSACryptoServiceProvider. Sử dụng phương thức
RSACryptoServiceProvider. Encrypt và khóa công khai (public key) của người
nhận để mật hóa thông điệp. Sau đo, người nhận sẽ sử dụng phương thức
RSACryptoServiceProvider.Decrypt và khóa riêng (private key) để giải mật hóa
bí mật đã-được-mật-hóa.
.NET Framework định nghĩa một hệ thống phân cấp theo lớp cho các giải thuật bất

đối
xứng tương tự như đã định nghĩa cho các giải thuật đối xứng (đã được thảo luận trong
mục 14.6). Tất cả các giải thuật bất đối xứng phải thừa kế một lớp cơ sở trừu tượng
chung có tên là System.Security.Cryptography.AsymmetricAlgorithm. Có hai hiện thực
giải thuật bất đối xứng cụ thể:
• System.Security.Cryptography.RSACryptoServiceProvider
• System.Security.Cryptography.DSACryptoServiceProvider
Vì có đuôi là CryptoServiceProvider nên cả
hai lớp này đều bọc lấy các chức năng do
Win32 CryptoAPI cung cấp. Tuy nhiên, chỉ có lớp RSACryptoServiceProvider là hỗ trợ
việc mật hóa dữ liệu. Lớp DSACryptoServiceProvider hiện thực Digital Signature
Algorithm (DSA), bạn có thể sử dụng giải thuật này chỉ để tạo chữ ký số (xem Federal
Information Processing Standard [FIPS] 186-2 tại [ để
biết thêm chi tiết về DSA).
Mặc dù bạn có thể tạo một đối tượng giải thuật bất đối xứng bằng phương thức tĩnh
Create của lớp cơ sở AsymmetricAlgorithm, nhưng bù lại bạn sẽ phải trả giá chút ít cho
việc này. Lớp AsymmetricAlgorithm không khai báo các phương thức mà
RSACryptoServiceProvider sử dụng để mật hóa và giải mật hóa dữ liệu. Thay vào đó,
bạn phải trực tiếp thể hiện hóa lớp RSACryptoServiceProvider bằng mộ
t trong các
phương thức khởi dựng của nó.
Trước khi mật hóa hay giải mật hóa dữ liệu với đối tượng RSACryptoServiceProvider,
bạn cần truy xuất các khóa thích hợp. Khóa của giải thuật bất đối xứng khác nhiều so với
khóa của giải thuật đối xứng. Thứ nhất, nó có hai thành phần: khóa công khai (public key)
và khóa riêng (private key). Thứ hai, thay vì chỉ là một dãy các byte được sinh ngẫu
nhiên, khóa bất đối xứng được tạo theo một cách th
ức đặc biệt. Có một mối quan hệ toán
đặc biệt giữa khóa công khai và khóa riêng; mối quan hệ này cho phép giải thuật bất đối
xứng mật hóa dữ liệu bằng một khóa và giải mật hóa dữ liệu bằng một khóa khác. Mỗi
giải thuật bất đối xứng sử dụng cách thức tạo khóa của chính nó, và các lớp hiện thực cụ

thể đóng gói các chức năng cần thiết để t
ạo ra các khóa mới.
Khóa công khai không cần được giữ bí mật và chủ sở hữu có thể tùy ý gửi nó cho bạn
thông qua e-mail, hoặc post nó lên một website hay một server phân phối khóa để mọi
người cùng thấy. Những ai muốn gửi bí mật thì sử dụng khóa công khai để mật hóa bí
mật. Sau đó, người nhận sử dụng khóa riêng để giải mật hóa bí mật. Khóa riêng phải
được giữ bí mật; những ai sở hữu khóa riêng đều có thể giải mậ
t hóa dữ liệu đã-được-
mật-hóa bằng khóa công khai.
Để tạo một bí mật được-mật-hóa-bất-đối-xứng, bạn phải có khóa công khai của người
nhận và nạp nó vào một đối tượng RSACryptoServiceProvider. Có hai cách nạp khóa
công khai:
• Sử dụng phương thức RSACryptoServiceProvider.ImportParameters để nhập một
cấu trúc System.Security.Cryptography.RSAParameters, cấu trúc này chứa thông tin
khóa công khai của người nhận. Chủ sở hữu có thể tạo cấu trúc RSAParameters
bằng ph
ương thức RSACryptoServiceProvider.ExportParameters và gửi nó cho bạn.
Tuy nhiên, người này có thể gửi cho bạn khóa công khai ở dạng byte, và bạn phải tự
nạp giá trị này vào cấu trúc RSAParameters.
• Sử dụng phương thức RSACryptoServiceProvider.FromXmlString để nạp dữ liệu
khóa công khai từ một chuỗi XML. Chủ sở hữu có thể tạo dữ liệu XML này bằng
phương thức RSACryptoServiceProvider.ToXmlString và gửi nó cho bạn.
#
Cả phương thức ExportParameters và ToXmlString của lớp
RSACryptoServiceProvider đều nhận một đối số luận lý, nếu là true, đối tượng
RSACryptoServiceProvider sẽ xuất cả khóa công khai và khóa riêng. Bạn chỉ
định giá trị này là false khi cần xuất khóa cho mục đích phân phối hay lưu trữ.
Một khi đã nạp khóa công khai của người nhận vào đối tượng
RSACryptoServiceProvider, bạn có thể mật hóa dữ liệu. Giải thuật bất đối xứng chậm
hơn giải thuật đối xứng khi mật hóa và giải mật hóa dữ liệu. Vì lý do này, bạn không nên

sử dụng giải thuật bất đối xứng để mật hóa lượng dữ liệu lớn. Thông thường, nếu cần mật
hóa lượng d
ữ liệu lớn, bạn nên sử dụng giải thuật đối xứng và rồi mật hóa khóa đối xứng
bằng giải thuật bất đối xứng để bạn có thể gửi khóa đối xứng cùng với dữ liệu. Mục 14.10
sẽ thảo luận về vấn đề này. Để bảo đảm tính nhất quán trong việc sử dụng, lớp
RSACryptoServiceProvider không hỗ trợ mô hình mật hóa và giải mật hóa d
ựa-trên-
System.IO.Stream (đã được sử dụng trong mục 14.6).
Để mật hóa dữ liệu với đối tượng RSACryptoServiceProvider, bạn hãy gọi phương thức
Encrypt, truyền cho nó một mảng byte chứa plaintext; Encrypt sẽ trả về một mảng byte
chứa ciphertext. Phương thức Encrypt cũng mhận một đối số luận lý cho biết kiểu
padding mà đối tượng RSACryptoServiceProvider sẽ sử dụng. Padding cho biết đối
tượng bất đố
i xứng sẽ xử lý plaintext như thế nào trước khi mật hóa. Padding bảo đảm
giải thuật bất đối xứng không cần xử lý từng khối dữ liệu, và bảo vệ ciphertext đối với
các dạng tấn công bằng mật mã. Diễn giải các dạng padding vượt quá phạm vi của quyển
sách này. Nói chung, nếu đang sử dụng Microsoft Windows XP trở về sau, bạn nên chỉ
định đối số
padding là true; nếu không, bạn phải chỉ định đối số padding là là false (nếu
không thì Encrypt sẽ ném ngoại lệ
System.Security.Cryptography.CryptographicException).
Giải mật hóa dữ liệu cũng đơn giản như mật hóa dữ liệu. Người nhận cần tạo một đối
tượng RSACryptoServiceProvider và nạp nó cùng với khóa riêng. Thông thường, khóa
này sẽ được lưu trữ trong một kho chứa khóa (key container) do CryptoAPI quản lý (sẽ
được thảo luận kỹ
hơn trong mục 14.9). Người nhận gọi
RSACryptoServiceProvider.Decrypt và truyền cho nó ciphertext mà bạn đã gửi. Người
nhận phải chỉ định cơ chế padding, và nó cũng phải giống như khi mật hóa dữ liệu.
Phương thức Decrypt trả về một mảng byte chứa plaintext đã-được-giải-mật-hóa. Nếu
plaintext mô tả một chuỗi, người nhận phải chuyển mảng byte thành giá trị chuỗi thích

hợp bằ
ng lớp System.Text.Encoding.
#
Lớp RSACryptoServiceProvider thừa kế các phương thức có tên là
EncryptValue và DecryptValue từ lớp cha của nó là
System.Security.Cryptography.RSA. Lớp RSACryptoServiceProvider không
hiện thực các phương thức này và ném ngoại lệ
System.NotSupportedException nếu bạn gọi chúng.
Lớp AsymmetricEncryptionExample dưới đây trình bày cách sử dụng lớp
RSACryptoServiceProvider để mật hóa một chuỗi và rồi giải mật hóa:
using System;
using System.Text;

×