2009-05-23 38 views
5

Tôi đang tìm một lớp mã hóa chuỗi chung trong .NET. (Không được nhầm lẫn với lớp 'SecureString'.)Mã hóa chuỗi chung

Tôi đã bắt đầu đưa ra lớp của riêng mình, nhưng nghĩ rằng phải có một lớp .NET đã cho phép bạn mã hóa/giải mã các chuỗi mã hóa bất kỳ bất kỳ Nhà cung cấp dịch vụ mã hóa nào.

Public Class SecureString 

     Private key() As Byte 
     Private iv() As Byte 
     Private m_SecureString As String 

     Public ReadOnly Property Encrypted() As String 
      Get 
       Return m_SecureString 
      End Get 
     End Property 

     Public ReadOnly Property Decrypted() As String 
      Get 
       Return Decrypt(m_SecureString) 
      End Get 
     End Property 

     Public Sub New(ByVal StringToSecure As String) 
      If StringToSecure Is Nothing Then StringToSecure = "" 
      m_SecureString = Encrypt(StringToSecure) 
     End Sub 

     Private Function Encrypt(ByVal StringToEncrypt As String) As String 

      Dim result As String = "" 
      Dim bytes() As Byte = Text.Encoding.UTF8.GetBytes(StringToEncrypt) 

      Using provider As New AesCryptoServiceProvider() 

       With provider 
        .Mode = CipherMode.CBC     
        .GenerateKey() 
        .GenerateIV() 
        key = .Key 
        iv = .IV 
       End With 

       Using ms As New IO.MemoryStream 
        Using cs As New CryptoStream(ms, provider.CreateEncryptor(), CryptoStreamMode.Write) 
         cs.Write(bytes, 0, bytes.Length) 
         cs.FlushFinalBlock() 
        End Using 
        result = Convert.ToBase64String(ms.ToArray()) 
       End Using 

      End Using 

      Return result 

     End Function 

     Private Function Decrypt(ByVal StringToDecrypt As String) As String 

      Dim result As String = "" 
      Dim bytes() As Byte = Convert.FromBase64String(StringToDecrypt) 

      Using provider As New AesCryptoServiceProvider() 

       Using ms As New IO.MemoryStream 
        Using cs As New CryptoStream(ms, provider.CreateDecryptor(key, iv), CryptoStreamMode.Write) 
         cs.Write(bytes, 0, bytes.Length) 
         cs.FlushFinalBlock() 
        End Using 
        result = Text.Encoding.UTF8.GetString(ms.ToArray()) 
       End Using 

      End Using 

      Return result 

     End Function 

    End Class 
+0

Uhm, bạn cần chuyển IV để giải mã. – Migol

+0

@Migol - Bạn có thể làm rõ thêm nhận xét của mình không? – user111370

+0

IV có thể được gửi qua opentext và chứa một số dữ liệu khác ngoài khóa để giải mã chuỗi của bạn. – Migol

Trả lời

4

Thuật toán mã hóa đối xứng thường là cách để mã hóa chung chuỗi. Tuy nhiên, tôi sợ rằng .NET BCL không đơn giản hóa mọi thứ thêm cho bạn về việc cung cấp các lớp và các hàm mã hóa/giải mã cơ bản.

Bạn có thể tìm thấy một ví dụ điển hình về cách sử dụng các lớp crypographic đặc biệt cho mã hóa chuỗi trên this page. Dường như nó rất hoàn chỉnh và được nhận xét rất tốt - thậm chí bạn có thể thấy rằng bạn có thể sử dụng nó mà không cần phải sửa đổi gì thêm. Lưu ý: Rijndael là cùng một thuật toán như AES. (. Về mặt kỹ thuật, cựu đề cập đến tên thật của thuật toán, và sau này các Advanced Encryption Standard)

+0

@Noldorin - Cảm ơn bạn đã liên kết! Có bất kỳ chức năng chung nào mà tôi có thể chuyển một chuỗi mã hóa bất kỳ và sử dụng bất kỳ Nhà cung cấp dịch vụ mật mã nào không? – user111370

+0

@cryptospin: Không sao cả. Chỉ cần nhận ra tôi hơi hiểu lầm câu hỏi ban đầu của bạn. Tôi vừa mới cập nhật bài đăng với nhiều thông tin hơn một chút. Chắc chắn không có lớp/phương thức trợ giúp nào trong .NET framework để làm điều này cho bạn, tôi sợ, mặc dù mã trên trang được liên kết sẽ cung cấp cho bạn một điểm khởi đầu tốt. Một cách tốt đẹp để đi về nó có thể là sử dụng các phương pháp mở rộng ở đây. – Noldorin

3

Nếu bạn đang cố gắng để đạt được cùng một mục tiêu như SecureString của .NET, sau đó ví dụ của bạn thực sự không giải quyết được vấn đề. (Tôi có thể hiểu sai mục tiêu của bạn, trong trường hợp này tôi xin lỗi.)

Ý tưởng của SecureString của .NET là lưu trữ dữ liệu chuỗi được mã hóa trong một bộ nhớ không được quản lý, là không thay đổi khi được tạo và không thể được đọc bằng .NET sử dụng biến chuỗi bình thường. Điều này bảo vệ chuỗi từ bất kỳ ai cố gắng thăm dò không gian bộ nhớ của bạn (tức là phần mềm độc hại, sâu, Trojan, bất kỳ thứ gì) và phải được dọn dẹp rõ ràng bởi bạn. Lý do cho việc này liên quan đến cách xử lý các chuỗi, và thực tế là dữ liệu trong bộ nhớ chỉ được làm sạch tại thời điểm của GC.

Mặc dù lớp SecureString của bạn mã hóa chuỗi thành biến riêng tư, chuỗi gốc đã được chuyển vào vẫn không an toàn. Nó cũng có thể dính xung quanh một lúc trước khi GC thu thập nó, hoặc, nếu chuỗi đó được tập trung, nó sẽ sống trong suốt quá trình nó nằm trong đó. Các chuỗi được lưu trữ được lưu trữ trong một bảng, điều này cũng giúp chúng dễ dàng tìm thấy hơn.

Ở phía bên kia của sự vật ... nếu bạn giải mã SecureString, bạn nhận được một biến chuỗi mới có thể chạy vào cùng các vấn đề như chuỗi đầu vào ... nó chỉ được dọn dẹp khi GC quyết định. ..và nó cũng có thể kết thúc tập trung và sống trong suốt quá trình.

Để giải quyết các vấn đề, mỗi lần bạn giải mã, bạn sẽ nhận được một bản sao của chuỗi được mã hóa của mình. Điều này có thể tạo ra thặng dư các phiên bản đã được giải mã của chuỗi bảo mật của bạn, tăng khả năng một số phần mềm độc hại đang dò tìm, ví dụ: số thẻ tín dụng ... sẽ thực sự tìm thấy một.

Tôi đã thử nhiều lần để tạo ra một phiên bản .NET giống như .NETStreet 2.0 của .NET 2.0 tốt hơn, nhưng chưa bao giờ có thể tạo ra thứ gì đó thực sự an toàn. Bạn có thể lấy một con trỏ tới biến chuỗi đã được giải mã, xóa nó, đặt từng ký tự thành nil, v.v. Tuy nhiên điều này có thể rất có vấn đề ngay cả khi cái gì đó vẫn còn tham chiếu đến chuỗi đó, làm cho văn bản biến mất, số lần đọc bị hỏng, v.v. Nếu chuỗi là tập trung, thường có nghĩa là nó đang được sử dụng bởi nhiều thứ trong một thời gian dài, lau nó sẽ xóa phiên bản duy nhất, và ảnh hưởng đến tất cả việc sử dụng nó.Ngay cả khi bạn quản lý thành công xóa một bản sao chuỗi an toàn của mình, không có gì đảm bảo rằng nó không được sao chép bởi mã khác trước khi bạn xóa nó (tức là bạn gửi chuỗi của bạn cho một số dịch vụ web ... không gian quá trình, có thể ở các địa điểm thực tế khác nhau trên thế giới.)

Đây là vấn đề phức tạp và thực sự cung cấp bảo mật trong trường hợp không gian bộ nhớ của ứng dụng của bạn bị xâm nhập bởi phần mềm độc hại.

+0

Cảm ơn bạn đã dành thời gian đăng bài. Nếu bạn đọc OP tôi làm rõ ràng nhà nước "(Không được nhầm lẫn với lớp 'SecureString'.)" – user111370

+0

"Điều này bảo vệ chuỗi từ bất cứ ai cố gắng để thăm dò không gian bộ nhớ của bạn" nó không và không nhằm mục đích. Nếu bạn có thể đọc bộ nhớ của một quá trình, bạn gần như chắc chắn có thể tiêm mã gốc, tại thời điểm đó trích xuất các bản rõ đằng sau 'SecureString' là tầm thường. Nó chỉ giữ chuỗi ra khỏi bãi đổ vỡ, tệp hoán đổi, v.v. – CodesInChaos

+0

@CodesInChaos: Văn bản không đơn giản, nó được mã hóa. Nếu một 'SecureString' đơn giản được lưu trữ văn bản thuần túy trên một vùng không quản lý, tôi đồng ý, nó có lẽ sẽ chỉ giữ nó ra khỏi bãi rác, tập tin hoán đổi, v.v. bộ nhớ của bạn ngay lập tức nhận được giá trị của nó. Chắc chắn, sức mạnh vũ phu hoặc các cuộc tấn công có thể biết (nếu có bất kỳ giao thức bảo mật nào của bạn) vẫn có khả năng phá vỡ mã hóa, nhưng đó là trường hợp kỹ thuật với mọi cơ chế bảo mật. Vì vậy, tôi đứng theo tuyên bố của tôi. – jrista

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