一般字符串加密

时间:2009-05-23 01:16:34

标签: .net cryptography

我正在寻找.NET中的通用字符串加密类。 (不要与'SecureString'类混淆。)

我已经开始提出我自己的类,但是认为必须有一个.NET类,它已经允许你使用任何加密服务提供程序加密/解密任何编码的字符串。

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

4 个答案:

答案 0 :(得分:4)

对称加密的AES算法通常是对字符串进行通用加密的方法。但是,我担心.NET BCL不会为您提供基本的加密/解密类和函数。

您可以找到一个很好的示例,说明如何在this page上专门用于字符串加密的加密类。它看起来非常完整,确实评论很好 - 您甚至可以发现无需进一步修改即可使用它。注意: Rijndael AES 的算法相同。 (从技术上讲,前者是指算法的真实姓名,后者是高级加密标准。)

答案 1 :(得分:3)

如果您尝试实现与.NET的SecureString相同的目标,那么您的示例确实无法解决问题。 (我可能会误解你的目标,在这种情况下我道歉。)

.NET的SecureString的想法是它将加密的字符串数据存储在非托管的内存块中,一旦创建就是不可变的,并且使用普通的字符串变量无法在.NET中读取。这可以保护字符串免受任何试图探测内存空间的人(即恶意软件,蠕虫,特洛伊木马等),并且必须由您明确清理。其原因涉及.NET如何处理字符串,以及内存中的数据只是在GC的奇思妙想中清理的事实。

即使您的SecureString类将字符串加密为私有变量,传入的原始字符串仍然不安全。它也可以在GC收集它之前保持一段时间,或者,如果该字符串被中断,它将在它所驻留的过程的持续时间内存活。 Interned字符串存储在表格中,这也使它们更容易找到。

另一方面......如果你解密你的SecureString,你得到一个新的字符串变量可能会遇到与输入字符串相同的问题...它只在GC决定时才被清除..并且它也可能最终在整个过程中被实习和生活。

要解决问题,每次解密时,您都会获得加密字符串的另一个副本。这可能会增加您的安全字符串的多余解密版本,从而增加了一些正在探测的恶意软件(比如信用卡号码)实际上会找到一个的机会。

我已多次尝试创建一个更好的,更像.NET的.NET 2.0版SecureString,但从未能够生成真正安全的东西。你可以获得一个指向解密的字符串变量的指针,擦除它,将每个字符设置为nil等。但是,即使某些东西仍然引用该字符串,导致文本消失,读取损坏等,这可能会非常有问题。如果字符串被中断,这通常意味着它被许多东西长时间使用,擦除它会擦除唯一的版本,并影响它的所有使用。即使您成功擦除了安全字符串的副本,也无法保证在您擦除它之前没有被其他代码复制(即您将字符串发送到某些Web服务...它现在生活在更多超过一个处理空间,很可能在世界各地不同的物理位置。)

它绝对是一个复杂的问题,只有在您的应用程序的内存空间被某种恶意软件泄露的情况下才真正提供安全性。

答案 2 :(得分:0)

答案 3 :(得分:0)