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

Mật mã ( Cryptography) phần cuối

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 (188.62 KB, 9 trang )

1.1
Lưu trữ khóa bất đối xứng một cách an toàn
V
V


Bạn cần lưu trữ cặp khóa bất đối xứng vào một nơi an toàn để ứng dụng của
bạn có thể truy xuất được dễ dàng.
#
#


Dựa vào chức năng lưu trữ khóa do hai lớp giải thuật bất đối xứng cung cấp
(RSACryptoServiceProvider và DSACryptoServiceProvider—thuộc không
gian tên System.Security.Cryptography).
Cả hai lớp giải thuật bất đối xứng—RSACryptoServiceProvider và
DSACryptoServiceProvider—đều bọc lấy các chức năng do CSP (Cryptographic Service
Provider—một thành phần của Win32 CryptoAPI) hiện thực. Ngoài các dịch vụ như mật
hóa, giải mật hóa, và chữ ký số, mỗi CSP còn cung cấp một kho ch
ứa khóa (key
container).
Kho chứa khóa là vùng lưu trữ dành cho các khóa mà CSP quản lý; CSP sử dụng cơ chế
bảo mật của hệ điều hành và phép mật hóa mạnh để bảo vệ nội dung của kho chứa khóa.
Kho chứa khóa cho phép ứng dụng dễ dàng truy xuất khóa mà không ảnh hưởng đến tính
bảo mật của khóa. Khi gọi các hàm của một CSP, ứng dụng cần chỉ định tên của kho
chứ
a khóa và CSP sẽ truy xuất các khóa cần thiết. Vì khóa không truyền từ CSP đến ứng
dụng nên ứng dụng không thể làm hại tính bảo mật của khóa.
Lớp RSACryptoServiceProvider và DSACryptoServiceProvider cho phép bạn cấu hình
hiện thực CSP nằm dưới bằng một thể hiện của lớp System.Security.Cryptography.
CspParameters. Để cấu hình cho một đối tượng RSACryptoServiceProvider hay


DSACryptoServiceProvider sử dụng một kho chứa khóa cụ thể, bạn phải hoàn tất các
bướ
c dưới đây:
1. Tạo một đối tượng CspParameters.
2. Thiết lập trường KeyContainerName của đối tượng CspParameters là một giá trị
chuỗi mô tả tên của kho chứa khóa cần sử dụng; chuỗi có thể chứa khoảng trắng.
3. Tạo một đối tượng RSACryptoServiceProvider hay DSACryptoServiceProvider, và
truyền đối tượng CspParameters làm đối số cho phương thức khởi dựng.
Nếu kho chứa khóa tồn tại bên trong tầm v
ực của CSP và chứa các khóa thích hợp, CSP
sẽ sử dụng các khóa này khi thực hiện các thao tác mật mã. Nếu kho chứa khóa hay khóa
không tồn tại, CSP sẽ tự động tạo khóa mới. Để buộc CSP lưu trữ các khóa mới được tạo
vào kho chứa khóa, bạn phải thiết lập thuộc tính PersistKeyInCsp (của đối tượng
RSACryptoServiceProvider hay DSACryptoServiceProvider) là true.
Phương thức LoadKeys dưới đây là một đoạn trích trong file
StoreAsymmetricKeyExample.cs (xem đĩa CD
đính kèm). LoadKeys tạo một đối tượng
RSACryptoServiceProvider và cấu hình cho nó sử dụng một kho chứa khóa có tên là
MyKeys. Bằng cách chỉ định PersistKeyInCsp là true, giải thuật sẽ tự động lưu trữ các
khóa mới được tạo vào kho chứa khóa này.
// Phương thức này tạo một đối tượng RSACryptoServiceProvider
// và nạp các khóa từ một kho chứa khóa nếu chúng tồn tại; nếu không,
// RSACryptoServiceProvider sẽ tự động tạo các khóa mới và lưu
// chúng vào kho chứa khóa để sử dụng sau này.
public static void LoadKeys(string container) {

// Tạo một đối tượng CspParameters và thiết lập trường
// KeyContainerName là tên của kho chứa khóa.
System.Security.Cryptography.CspParameters cspParams =
new System.Security.Cryptography.CspParameters();

cspParams.KeyContainerName = container;

// Tạo một đối tượng giải thuật RSA và truyền đối tượng
// CspParameters làm đối số trong phương thứ
c khởi dựng.
using (System.Security.Cryptography.RSACryptoServiceProvider
rsaAlg = new
System.Security.Cryptography.RSACryptoServiceProvider(cspParams)){

// Cấu hình cho đối tượng RSACryptoServiceProvider
// lưu trữ khóa vào kho chứa khóa.
rsaAlg.PersistKeyInCsp = true;

// Hiển thị PUBLIC KEY.
System.Console.WriteLine(rsaAlg.ToXmlString(false));
}
}
Lớp RSACryptoServiceProvider và DSACryptoServiceProvider không cung cấp phương
thức nào trực tiếp gỡ bỏ kho chứa khóa. Để xóa các khóa đã được lưu trữ, bạn hãy thiết
lập giá trị của PersistKeyInCsp là false và gọi phương thức Clear hay Dispose của đối
tượng RSACryptoServiceProvider hay DSACryptoServiceProvider. Phương thức
DeleteKeys dưới đây sẽ trình bày kỹ thuật này:
// Phương thức này tạo một đối tượng RSACryptoServiceProvider
// và xóa các khóa hiện có khỏi kho chứa khóa.
public static void DeleteKeys(string container) {

// Tạo một đối tượng CspParameters và thiết lập trường
// KeyContainerName là tên của kho chứa khóa cần xóa.
System.Security.Cryptography.CspParameters cspParams =
new System.Security.Cryptography.CspParameters();

cspParams.KeyContainerName = container;

// Tạo một đối tượng giải thuật RSA và truyền đối tượng
// CspParameters làm đối số trong phương thức khởi dựng.
using (System.Security.Cryptography.RSACryptoServiceProvider
rsaAlg = new
System.Security.Cryptography.RSACryptoServiceProvider(cspParams)){

// Cấu hình cho đối tượng RSACryptoServiceProvider
// không lưu trữ khóa vào kho chứa khóa.
rsaAlg.PersistKeyInCsp = false;

// Hiển thị PUBLIC KEY. Vì chúng ta gọi Dispose()
// sau lời gọi này nên các khóa hiện có sẽ không thay đổi
// cho đến khi phương thức được gọi lần thứ hai.
System.Console.WriteLine(rsaAlg.ToXmlString(false));

// Vì mã lệnh nằm trong khối "using" nên Dispose được gọi
// trên đố
i tượng RSACryptoServiceProvider. Vì đối tượng
// này được cấu hình là không lưu trữ khóa nên kho chứa khóa
// sẽ bị xóa. Thay vì gọi Dispose(), gọi rsaAlg.Clear()
// sẽ có cùng tác dụng, vì nó gián tiếp gọi Dispose().
}
}
Win32 CryptoAPI hỗ trợ cả user-key-store và machine-key-store. Hệ điều hành Windows
bảo đảm một user-key-store chỉ có thể được truy xuất bởi người đã tạo ra nó, nhưng một
machine-key-store có thể được truy xuất bởi bất kỳ người dùng nào của máy. Theo mặc
định, lớp RSACryptoServiceProvider và DSACryptoServiceProvider sẽ sử dụng user-
key-store. Bạn có thể chỉ định sử dụng machine-key-store bằng cách thiết l

ập thuộc tính
tĩnh UseMachineKeyStore của lớp RSACryptoServiceProvider hay
DSACryptoServiceProvider là true. Điều này sẽ có tác dụng với tất cả mã lệnh đang chạy
trong miền ứng dụng hiện hành. Nếu muốn kiểm soát chặt chẽ hơn, bạn có thể thiết lập
thuộc tính CspParameters.Flags là giá trị
System.Security.Cryptography.CspProviderFlags.UseMachineKeyStore trước khi tạo đối
tượng mật hóa bất đối xứng.
#
Bạn nên xét các yêu cầu bảo mật một cách cẩn thận trước khi chọn sử dụng
machine-key-store. Thực tế là người dùng nào có quyền truy xuất máy đều có
thể giành được quyền truy xuất các khóa trong kho lưu trữ, điều này phủ định
hầu hết các lợi ích do phép mật hóa bất đối xứng mang lại.
1.2
Trao đổi khóa phiên đối xứng một cách an toàn
V
V


Bạn cần trao đổi dữ liệu đã-được-mật-hóa-đối-xứng với ai đó, và bạn cần một
biện pháp an toàn để phân bổ khóa phiên (session key) đối xứng cùng với dữ
liệu.
#
#


Sử dụng cơ chế trao đổi khóa do lớp System.Security.Cryptography.
RSACryptoServiceProvider hiện thực. Theo cơ chế này, khóa đối xứng sẽ được
mật hóa bất đối xứng bằng khóa công khai (public key) của người nhận. Theo
đó, bạn có thể gửi khóa đối xứng đã-được-mật-hóa cùng với dữ liệu đã-được-
mật-hóa. Người nhận phải giải mật hóa khóa đối xứng bằng khóa riêng (private

key), rồi m
ới tiến hành giải mật hóa dữ liệu.
Mỗi khi mật hóa dữ liệu (bằng giải thuật đối xứng) để chuyển giao, bạn nên tạo một khóa
mới, được gọi là khóa phiên (session key). Sử dụng khóa phiên có hai lợi ích chính:
• Nếu ai đó (không được phép) lấy được nhiều khối ciphertext đã được mật hóa bằng
cùng một khóa đối xứng, khả năng người đó giải được dữ
liệu sẽ tăng cao.
• Nếu ai đó tìm được khóa phiên của bạn, người này chỉ có thể truy xuất được một tập
dữ liệu nào đó đã-được-mật-hóa, chứ không phải tất cả các bí mật của bạn ở quá
khứ và tương lai.
Vấn đề đối với khóa phiên là phân bổ và bảo mật khóa. Một giải pháp là thỏa thuận một
lượng lớn khóa phiên với nhữ
ng người mà bạn cần trao đổi dữ liệu với họ. Thật không
may, việc này nhanh chóng trở nên khó quản lý; và thực tế là tất cả các khóa của bạn
trong tương lai đều được lưu trữ tại một nơi nào đó, điều này tăng khả năng chúng sẽ bị
xâm hại. Cách tốt hơn là gửi khóa phiên theo một dạng được mật hóa mạnh cùng với dữ
liệu mà bạn đã m
ật hóa với khóa đó—quá trình này được gọi là trao đổi khóa (key
exchange).
Quá trình trao đổi khóa sử dụng phép mật hóa bất đối xứng để mật hóa khóa phiên đối
xứng. Nếu muốn gửi dữ liệu cho ai đó, bạn tạo một khóa phiên đối xứng, mật hóa dữ liệu,
và rồi mật hóa khóa phiên bằng khóa công khai của người nhận. Khi nhận được dữ liệu,
người nhận giải mật hóa khóa phiên b
ằng khóa riêng của họ, và rồi giải mật hóa dữ liệu.
Quan trọng là việc trao đổi khóa cho phép bạn trao đổi các lượng dữ liệu lớn (đã-được-
mật-hóa) với bất cứ ai, thậm chí những người bạn chưa từng tiếp xúc trước đây, miễn là
bạn có thể truy xuất khóa công khai đối xứng của họ.
#
Một cách lý tưởng, bạn sử dụng một giải thuật bất đối xứng để mật hóa tất cả
dữ liệu, như thế tránh được nhu cầu trao đổi các khóa đối xứng. Tuy nhiên, tốc

độ của các giải thuật bất đối xứng khi mật hóa và giải mật hóa dữ liệu khiến
chúng không thực tế cho việc sử dụng với các lượng lớn dữ liệu. Sử dụng các
giải thuật bất đối xứng để mật hóa các khóa phiên đối xứng là một giải pháp
tuy phức tạp hơn, nhưng là tốt nhất ở cả hai mặt: tính linh hoạt và tính nhanh
chóng.
Thư viện lớp .NET Framework hỗ trợ việc trao đổi khóa chỉ với giải thuật RSA, nhưng
bạ
n phải lựa chọn giữa hai formatting scheme: Optimal Asymmetric Encryption Padding
(OAEP) và PKCS #1 v 1.5. Bàn về các formatting scheme này vượt quá phạm vi của
quyển sách này. Nói chung, bạn nên sử dụng OAEP formatting trừ khi bạn có nhu cầu
giao tiếp với một hệ thống cũ có sử dụng PKCS formatting. Hai lớp dưới đây hiện thực
cơ chế trao đổi khóa, mỗi cơ chế ứng với một formatting scheme:
• System.Security.Cryptography.RSAOAEPKeyExchangeFormatter
• System.Security.Cryptography.RSAPKCS1KeyExchangeFormatter
Để chuẩn bị một khóa đối xứng dùng cho trao đổi, bạn phải tạo một đối tượng formatter
với kiểu như mong muốn và rồi ấn định một đối tượng giải thuật bất đối xứng
(RSACryptoServiceProvider) cho formatter bằng phương thức SetKey của formatter.
Bạn phải cấu hình cho giải thuật bất đối xứng sử dụng khóa công khai củ
a người nhận.
Khi đã cấu hình xong, gọi phương thức CreateKeyExchange của formatter và truyền một
mảng byte chứa khóa phiên đối xứng mà bạn cần định dạng. Phương thức
CreateKeyExchange trả về một mảng byte chứa dữ liệu bạn sẽ gửi đi.
Giải định dạng cho khóa ngược với quá trình định dạng. Có hai lớp deformatter, mỗi lớp
ứng với một formatting scheme.

System.Security.Cryptography.RSAOAEPKeyExchangeDeformatter
• System.Security.Cryptography.RSAPKCS1KeyExchangeDeformatter
Để giải định dạng một khóa phiên đã được định dạng, hãy tạo một đối tượng deformatter
với kiểu phù hợp rồi gọi phương thức SetKey của nó để ấn định một đối tượng giải thuật
bất đối xứng. Bạn phải nạp khóa riêng của bạn vào giải thuật bất đối xứng. Cuối cùng,

gọi phương th
ức DecryptKeyExchange với đối số là dữ liệu trao đổi. Phương thức này trả
về một mảng byte chứa khóa phiên đối xứng gốc.
File KeyExchangeExample.cs chứa ví dụ minh họa cho việc trao đổi khóa. Phương thức
Main mô phỏng việc tạo, định dạng, trao đổi, và giải định dạng một khóa phiên đối xứng.
Nó sẽ tạo một cặp khóa bất đối xứng để sử dụng cho cả ví dụ
này. Thực tế, người gửi
(người tạo khóa đối xứng) chỉ có khóa công khai của người nhận; người nhận có khóa
riêng (được giữ bí mật).
#
Cũng như nên sử dụng một khóa đối xứng có chiều dài phù hợp với tính bí mật
của dữ liệu đang được bảo vệ, bạn nên mật hóa khóa phiên bằng một giải thuật
bất đối xứng và chiều dài khóa ít nhất cũng phải tương đương với khóa đối

×