C#-寻找加密/解密方法

C#-寻找加密/解密方法,c#,encryption,C#,Encryption,我写了一篇C#文章,它使用RtlEncryptMemory/rtldecyptmemory对字符串进行加密/解密。然后,这个字符串保存在一个配置文件中,这一切都很好,但问题是,一旦我注销/登录,我就无法再解密该字符串。我正在使用RTL_ENCRYPT_OPTION_SAME_LOGON选项,这意味着内部机制使用Windows会话中的某些内容来执行解密。我正在寻找一个解决方案,以同样的方式工作,但与网络用户(或令牌等)绑定。Windows是否已经提供了一些功能 我的目标是,只要进程在同一用户(网络

我写了一篇C#文章,它使用RtlEncryptMemory/rtldecyptmemory对字符串进行加密/解密。然后,这个字符串保存在一个配置文件中,这一切都很好,但问题是,一旦我注销/登录,我就无法再解密该字符串。我正在使用RTL_ENCRYPT_OPTION_SAME_LOGON选项,这意味着内部机制使用Windows会话中的某些内容来执行解密。我正在寻找一个解决方案,以同样的方式工作,但与网络用户(或令牌等)绑定。Windows是否已经提供了一些功能

我的目标是,只要进程在同一用户(网络凭据)下运行,就能够从任何地方解密字符串。我也不想让用户输入密码或使用内部值,因为这可能会受到损害。理想情况下,它将与RTL函数一样,但提供RTL加密选项\ustrong>相同用户选项

谢谢! Nic

我已经有一段时间没有使用c#了,但通常c#中的加密和解密库使用机器密钥作为散列密钥。如果应用程序位于不同的服务器中,请确保在所有服务器中将机器密钥设置为相同的值,或者如果可以覆盖该方法,则可以使用不同的密钥,该密钥由某个密码短语生成

我有一个Nuget软件包,您可能会喜欢:

DataJuggler.Net.Cryptography.Net框架

DataJuggler.Core.Cryptography点网核心

使用起来非常简单,下面是一个现场演示:

上面还提供了源代码和视频链接

用法:

加密:

// get the encryptedText
encryptedResult = CryptographyHelper.EncryptString(textToEncrypt, keyCode);
解密:

// get thedecryptedText
decryptedResult = CryptographyHelper.DecryptString(textToDecrypt, keyCode);
它还包括密码散列


如果您认为它值得免费使用,请告诉我。

如果您想存储字符串,则不应使用RtlEncryptMemory,因为它仅用于在运行的应用程序内存中保持字符串的安全,因此可以存储/序列化和解密


请看一看,我认为它应该满足您的需要。

您想使用DataProtection API吗

下面是一个添加加密和解密字符串扩展名的简单实现

public static class StringExtensions
{
    public static string Encrypt(this string s)
    {
        if (String.IsNullOrEmpty(s))
        {
            return s;
        }
        else
        {
            var encoding = new UTF8Encoding();
            byte[] plain = encoding.GetBytes(s);
            byte[] secret = ProtectedData.Protect(plain, null, DataProtectionScope.CurrentUser);
            return Convert.ToBase64String(secret);
        }
    }
    public static string Decrypt(this string s)
    {
        if (String.IsNullOrEmpty(s))
        {
            return s;
        }
        else
        {
            byte[] secret = Convert.FromBase64String(s);
            byte[] plain = ProtectedData.Unprotect(secret, null, DataProtectionScope.CurrentUser);
            var encoding = new UTF8Encoding();
            return encoding.GetString(plain);
        }
    }
}
这里有一个例子

    class Program
{
    static void Main(string[] args)
    {
        string password = "Monkey123";
        string encrypted = password.Encrypt();
        Console.WriteLine($"Encrypted password = '{encrypted}'");
        string decrypted = encrypted.Decrypt();
        Console.WriteLine($"Decrypted password = '{decrypted}'");
    }
}
它产生了这个输出

Encrypted password = 'AQAAANCMnd8BFdERjHoAwE/Cl+sBAAAA/6wDgM21DkStrNJQ35QDiwAAAAACAAAAAAAQZgAAAAEAACAAAAAPr3/aqafbt/RRoPVe75b+PFBhE6h9MLcQ2Ivsd3adOwAAAAAOgAAAAAIAACAAAABYxqEdzotL+7qXpWnbbpPRkfWZF6oh/meFsXzFtLPnrBAAAAB59VGbboP4Tye1N3dB7E3jQAAAAMQn8cAlnTDe1mwDEJriADizdT2Qr0DtPgpMje+rbjdkVpL+cKiEQs4om4i1hlLPgPn5MG5oVWFFnxU0d4c9TFg='
Decrypted password = 'Monkey123'
注:

  • 只有当前登录的用户才能解密使用此代码加密的数据。只要当前用户具有漫游配置文件,此功能就可以在网络上运行
  • 或者,作用域可以是本地计算机,在这种情况下,只有登录到同一计算机的用户才能解密数据
  • 这是.NET核心3.1代码,仅适用于Windows计算机
  • 使用语句

    using System;
    using System.Security.Cryptography;
    using System.Text;
    

    如果你想存储字符串,就不应该使用RtlEncryptMemory,因为它只在运行的应用程序内存中保证字符串的安全,因此可以存储/序列化和解密。看看这个线程,我认为DPAPI可以满足你的需要。是的,我完全理解RtlEncryptMemory不是一个好办法。看起来凯文的建议可能是可行的,我将不得不制作这个原型。谢谢你的回复。我刚刚测试完Kevin的DPAPI建议,这是最符合我要求的。不幸的是,加密数据仍然绑定到机器密钥,但它比我最初使用RTL的实现要好。凯文:如果你不介意把你的建议作为一个解决方案发布,我可以把它标记为接受。谢谢@完成!很高兴它有帮助。谢谢你的建议,看起来是一个很棒的软件包,不幸的是,它使用了一个关键代码或密码短语,如果可能的话,我希望避免使用。