2011-08-08 33 views
33

Theo nội dung MSDN SecureStringđược mã hóa để đảm bảo an toàn hơn để nếu chương trình được đổi chỗ thành đĩa, nội dung chuỗi không thể bị ngửi.SecureString được "mã hóa" và vẫn có thể sử dụng được như thế nào?

Tôi có thể tự hỏi mã hóa như thế nào? Thuật toán sẽ được cố định và do đó nổi tiếng hoặc được khấu trừ (nói một trong bảy thuật toán được sử dụng rộng rãi trong các thuật toán công nghiệp) và phải có khóa ở đâu đó trong chương trình. Vì vậy, kẻ tấn công có thể lấy chuỗi đã mã hóa, tìm khóa và giải mã dữ liệu.

Cách mã hóa như vậy có thể hữu ích?

+0

Nó không nói là an toàn, chỉ * an toàn hơn * –

+0

@Mark Peters: Đó là lý do tại sao tôi nói * an toàn bổ sung *. – sharptooth

+0

bạn có thể hỏi điều này tại crypto.SE - rất chủ đề có –

Trả lời

15

Tôi trích dẫn từ một bài viết về số DPAPI được sử dụng để lấy chìa khóa. Điều này sẽ trả lời hầu hết các câu hỏi mà bạn có về SecureString. Và có, SecureString có nhược điểm và không hoàn toàn an toàn, có nhiều cách để truy cập dữ liệu, ví dụ, tiêm Hawkeye vào quá trình được đề cập trên MSDN như một cách để trích xuất SecureString. Tôi đã không đích thân xác minh lời khẳng định này.

DAPI Key Management

DAPI là một đối xứng dựa kỹ thuật mã hóa, có nghĩa là nó sử dụng cùng một chìa khóa cho cả hai mã hóa và giải mã dữ liệu. Trước khi tìm hiểu một số ví dụ về cách sử dụng DAPI, nó đáng để biết cách DAPI quản lý khóa của nó như thế nào. Đối với hầu hết các phần của quá trình quản lý khóa DAPI là invisble và bạn thường không cần phải lo lắng về nó, đó là lý do chính tại sao DAPI là một cách tiếp cận tốt.

Trong phần giới thiệu, tôi đã viết rằng khóa chính được tạo từ mật khẩu đăng nhập của người dùng. Đây không phải là bức tranh hoàn chỉnh. Điều thực sự xảy ra là Windows sử dụng mật khẩu đăng nhập của người dùng để tạo khóa chính. Khóa chính này được bảo vệ bằng mật khẩu của người dùng và sau đó được lưu trữ cùng với hồ sơ của người dùng. Khóa chính này sau đó được sử dụng để lấy được một số khóa khác và đó là các khóa khác được sử dụng để bảo vệ dữ liệu.

Lý do tại sao Windows thực hiện điều này là nó cho phép ứng dụng thêm thông tin bổ sung, được gọi là entropy, vào quá trình tạo khóa cá nhân. Bạn thấy nếu mọi ứng dụng chạy dưới tài khoản đăng nhập của người dùng sử dụng cùng một khóa thì mọi ứng dụng đều có thể bảo vệ dữ liệu được bảo vệ bởi DAPI. Đôi khi bạn có thể muốn các ứng dụng có thể chia sẻ dữ liệu được bảo vệ DAPI; Tuy nhiên, đôi khi bạn sẽ không. Bằng cách cho phép ứng dụng đóng góp entropy vào việc tạo ra một khóa thì khóa đó sẽ trở thành ứng dụng cụ thể và bất kỳ dữ liệu nào được bảo vệ bởi ứng dụng đó chỉ có thể được bảo vệ một lần nữa nếu chúng biết entropy.

Mặc dù tạo khóa chính, và sau đó sử dụng khóa chính để tạo các khóa khác để thực hiện mã hóa thực, có vẻ giống như một cách tiếp cận dài, nó có một lợi thế lớn. Vì có một mức trừu tượng bổ sung giữa khóa chủ được bảo vệ bằng mật khẩu người dùng và các khóa thực tế được sử dụng để bảo vệ dữ liệu, nghĩa là khi người dùng thay đổi mật khẩu của họ thì chỉ có khóa chính cần được bảo vệ lại; không có dữ liệu được bảo vệ nào cần được bảo vệ lại. Vì khóa chính nhỏ hơn nhiều so với dữ liệu nên việc thực hiện tiết kiệm đáng kể.

Khi mật khẩu của người dùng thay đổi thì khóa học chính mới được tạo. Khóa chính mới này sau đó được sử dụng để tạo các khóa riêng mới. Tuy nhiên, vì tất cả các khóa cá nhân được tạo trước đây đều được lấy từ khóa chính cũ nên Windows cần lưu trữ tất cả các khóa chính trước đó, mà nó thực hiện. Windows không bao giờ quên khóa chính và tất cả dữ liệu được bảo vệ được đánh dấu bằng GUID cho biết khóa chính nào được sử dụng để bảo vệ dữ liệu. Vì vậy, xét về khả năng thích ứng, DAPI có thể đối phó với những thay đổi mật khẩu của người dùng, trong khi đảm bảo a) dữ liệu được bảo vệ không cần phải được bảo vệ lại và b) các khóa đó được sử dụng để bảo vệ dữ liệu trước đó.) nó thực hiện tất cả điều này tự động cho bạn.

Trừ khi máy tính là thành viên của miền DAPI chỉ có thể bảo vệ dữ liệu trên cùng một máy đã được sử dụng để bảo vệ nó.

Cũng như cho phép bảo vệ cấp người dùng, trong các khóa chính dựa trên mật khẩu người dùng và dữ liệu được bảo vệ cho một người dùng không được người dùng khác bảo vệ, DAPI cũng cung cấp mức bảo vệ máy. thông tin cụ thể. Các phím chính cấp máy cho phép các ứng dụng lưu trữ dữ liệu được bảo vệ sao cho nó có thể không được bảo vệ bởi tất cả người dùng của ứng dụng. Sự khác biệt duy nhất trong quá trình đã được mô tả là khóa chính được tạo từ thông tin cụ thể của máy chứ không phải thông tin cụ thể của người dùng.

+1

+1 để cho chúng tôi biết về Hawkeye –

+0

Tôi nghĩ rằng điều quan trọng để lấy đi từ bài viết được đăng là "Đối với hầu hết các phần quy trình quản lý khóa DAPI là invisble và bạn thường không cần phải lo lắng về nó ". Điều đó đúng ở đó làm cho tôi nghiêng về phía một giải pháp tùy chỉnh. Bảo vệ đủ tốt không phải luôn luôn, tốt, đủ tốt. –

+0

Lưu ý: Kể từ ngày 18 tháng 5 năm 2017, liên kết bài viết trả về 404: http://www.dsmyth.net/wiki/Print.aspx?Page=StudyNotes_DAPI – iokevins

11

Tôi đã xem xét một điểm vào mã cho nó và nó sử dụng advapi32 của Windows để thực hiện công việc bẩn thỉu của nó. Vì vậy, chìa khóa không được lưu trữ trong bộ nhớ của ứng dụng.

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] 
[DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] 
internal static int SystemFunction040([In, Out] SafeBSTRHandle pDataIn, [In] uint cbDataIn, [In] uint dwFlag) 

Đó là biết đến nhiều hơn như RtlEncryptMemory.

Nó giải mã với RtlDecryptMemory (SystemFunction041).

Tôi chắc chắn trình biên dịch cũng thực hiện điều gì đó với số SecurityCriticalAttribute.

chỉnh sửa điều này được phản ánh bằng cách sử dụng 4.0. các phiên bản khác có thể khác nhau.

2

Bằng sự kỳ diệu của DPAPI:

Lớp này lưu trữ dữ liệu của mình bằng cách sử dụng API Data Protection (DPAPI) bảo vệ mô hình bộ nhớ. Nói cách khác, dữ liệu luôn ở dạng mã hóa của nó trong khi nó được lưu trữ bên trong một SecureString. Khóa mã hóa được quản lý bởi hệ thống con của cơ quan bảo mật cục bộ (LSASS.EXE) và thông qua DPAPI, dữ liệu có thể được giải mã thông qua liên lạc giữa các tiến trình.

7

Khi người khác đã trả lời, nội dung của SecureString được mã hóa bằng DPAPI, vì vậy các khóa không được lưu trữ trong ứng dụng của bạn, chúng là một phần của hệ điều hành. Tôi không phải là 100% tích cực, nhưng tôi giả định rằng SecureString sử dụng khóa người dùng cụ thể, để ngay cả khi một quy trình khác có quyền truy cập vào khối bộ nhớ, nó sẽ phải chạy dưới cùng một thông tin xác thực để giải mã đơn giản nội dung bằng DPAPI. Thậm chí nếu không, chìa khóa máy (theo lý thuyết) ngăn không cho giải mã được giải mã nếu được chuyển sang một hệ thống khác.

Quan trọng hơn với SecureString là cách & khi bạn sử dụng. Nó nên được sử dụng để lưu trữ dữ liệu chuỗi cần được giữ lại trong bộ nhớ cho các khoảng thời gian "mở rộng", nhưng không thường xuyên cần thiết trong biểu mẫu được giải mã của chúng. Tại một thời điểm nào đó, bạn sẽ phải giải mã nó thành một mã thông thường cũ System.String hoặc System.Char[]. Đây là khi nó dễ bị tổn thương nhất trong bộ nhớ. Nếu bạn làm điều này quá thường xuyên, sau đó bạn có nhiều bản sao của chuỗi giải mã nổi xung quanh trong bộ nhớ đang chờ để được thu thập.

Theo nguyên tắc chung, nếu tôi đọc dữ liệu được mã hóa (nói thông tin xác thực đăng nhập) mà tôi cần giữ lại để sử dụng không thường xuyên (ví dụ: tương tác PayPal hoặc Amazon API), thì lưu trữ/lưu trữ các thông tin đăng nhập đó là SecureString, sau đó giải mã nó khi cần thiết chỉ đủ lâu để thực hiện các cuộc gọi dịch vụ web và đảm bảo rằng tuổi thọ của bất kỳ bản sao đã giải mã nào chỉ là một vài dòng mã. Nó có lẽ cũng khôn ngoan để sử dụng các khối quan trọng hoặc tương tự như gợi ý cho CLR rằng nó không nên chuyển ngữ cảnh trong khi chuỗi giải mã được sử dụng, để cải thiện cơ hội mà bất kỳ bản sao đã giải mã nào được thu thập trước khi bộ nhớ được lưu trong bộ nhớ cache hoặc đổi chỗ.

Các vấn đề liên quan