.net 通用字符串加密

.net 通用字符串加密,.net,cryptography,.net,Cryptography,我正在寻找.NET中的通用字符串加密类。(不要与“SecureString”类混淆。) 我已经开始设计我自己的类,但我认为一定有一个.NET类已经允许您使用任何加密服务提供商对任何编码的字符串进行加密/解密 Public Class SecureString Private key() As Byte Private iv() As Byte Private m_SecureString As String Public Rea

我正在寻找.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
对称加密算法通常是字符串的通用加密方法。然而,我担心.NET BCL不会为您进一步简化事情,因为它提供了基本的加密/解密类和函数

您可以找到一个很好的示例,说明如何使用crypographic类专门用于上的字符串加密。它看起来非常完整,评论也很好——你甚至会发现,你可以不做任何进一步的修改就使用它。注:Rijndael与AES的算法相同。(从技术上讲,前者指的是算法的真实名称,后者指的是高级加密标准。)

以下是SO的一个:


如果您试图实现与.NET的SecureString相同的目标,那么您的示例实际上并不能解决问题。(我可能误解了你的目标,在这种情况下,我道歉。)


NET的SecureString的思想是,它将加密的字符串数据存储在非托管内存块中,一旦创建就不可变,并且不能使用普通字符串变量在.NET中读取。这可以防止任何人试图探测您的内存空间(即恶意软件、蠕虫、特洛伊木马等),并且必须由您明确清除该字符串。这样做的原因包括.NET如何处理字符串,以及内存中的数据只是在GC一时兴起的情况下才被清除的事实

即使SecureString类将该字符串加密为私有变量,传入的原始字符串仍然是不安全的。它还可以在GC收集它之前停留一段时间,或者,如果该字符串被插入,它将在它所在的进程期间保持有效。插入的字符串存储在一个表中,这也使它们更容易找到

另一方面,如果你解密你的SecureString,你会得到一个新的字符串变量,这个变量可能会遇到与输入字符串相同的问题…只有当GC决定清理它时,它才会被清理…而且它也可能会在整个过程中被拘留和使用

为了使问题更加复杂,每次解密时,都会得到加密字符串的另一个副本。这可能会造成安全字符串的解密版本过剩,从而增加某些恶意软件(例如,正在探测信用卡号码的恶意软件)实际找到一个的可能性

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

这无疑是一个复杂的问题,只有在应用程序的内存空间被某种恶意软件破坏的情况下,它才能真正提供安全性。

这里有一个很好的解决方案


Link Txt:

Uhm,您需要通过IV进行解密。@Migol-您能进一步澄清您的评论吗?IV可以通过opentext发送,并且包含一些除密钥以外的数据来解密字符串。@Noldorin-谢谢您的链接!是否有任何通用函数可以传递任何编码的字符串并使用任何加密服务提供程序?@cryptospin:没问题。刚意识到我有点误解了你原来的问题。无论如何,我刚刚用更多的信息更新了这篇文章。在.NET framework中,恐怕没有帮助器类/方法可以帮您完成这项工作,尽管链接页面上的代码应该为您提供一个良好的起点。一个很好的方法是在这里使用扩展方法。感谢您花时间发布。如果您阅读OP I do EXPLICIT state“(不要与“SecureString”类混淆)。“这可以保护字符串不受任何试图探测内存空间的人的攻击”它不会也不打算这样做。如果您可以读取进程的内存,那么几乎可以肯定您也可以注入本机代码,此时提取
SecureString
s后面的纯文本非常简单。它只将字符串保存在崩溃转储、交换文件等之外@CodesInChaos:文本不是纯文本,而是加密的。如果
SecureString
只是将纯文本存储在一个非托管堆上,我同意,它可能只会使它远离崩溃转储、交换文件等。鉴于字符串是加密的,它可以保护任何可能正在探测内存的人不立即获得它的值。当然,暴力或可能已知的攻击(如果您的安全协议有任何攻击)仍有可能破坏加密,但从技术上讲,每种安全机制都是如此。所以我坚持我的说法。@jrista实际上,任何有权读取进程内存的进程都可以调用
CreateRemoteThread
,而不是调用DPAPI来解密字符串的代码。因此,
SecureString
无法防范特洛伊木马,只能防范意外泄漏。这假设进程拥有实际权限。如果一个过程有权利,我同意你的观点。还有其他阅读备忘录的方法