簡體   English   中英

如何在我的應用程序中加密用戶設置(例如密碼)?

[英]How can I encrypt user settings (such as passwords) in my application?

我想為用戶提供加密保存個人數據的能力。 這可能是微不足道的,或者可能已經被問到,但我找不到加密/解密密碼的易於使用的方法的示例。

我真的不需要任何超級魔法無法破解的密碼。 我只需要密碼很難破解。

我看過一些 MSDN 和 SO 問題,但沒有找到可用的東西。

大衛,我認為你的回答很漂亮,但我認為這些作為擴展方法會更漂亮。 這將允許這樣的語法:

string cypherText;
string clearText;

using (var secureString = "Some string to encrypt".ToSecureString())
{
    cypherText = secureString.EncryptString();
}

using (var secureString = cypherText.DecryptString())
{
    clearText = secureString.ToInsecureString();
}

這是更新后的代碼:

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Cryptography;
using System.Text;

public static class SecureIt
{
    private static readonly byte[] entropy = Encoding.Unicode.GetBytes("Salt Is Not A Password");

    public static string EncryptString(this SecureString input)
    {
        if (input == null)
        {
            return null;
        }

        var encryptedData = ProtectedData.Protect(
            Encoding.Unicode.GetBytes(input.ToInsecureString()),
            entropy,
            DataProtectionScope.CurrentUser);

        return Convert.ToBase64String(encryptedData);
    }

    public static SecureString DecryptString(this string encryptedData)
    {
        if (encryptedData == null)
        {
            return null;
        }

        try
        {
            var decryptedData = ProtectedData.Unprotect(
                Convert.FromBase64String(encryptedData),
                entropy,
                DataProtectionScope.CurrentUser);

            return Encoding.Unicode.GetString(decryptedData).ToSecureString();
        }
        catch
        {
            return new SecureString();
        }
    }

    public static SecureString ToSecureString(this IEnumerable<char> input)
    {
        if (input == null)
        {
            return null;
        }

        var secure = new SecureString();

        foreach (var c in input)
        {
            secure.AppendChar(c);
        }

        secure.MakeReadOnly();
        return secure;
    }

    public static string ToInsecureString(this SecureString input)
    {
        if (input == null)
        {
            return null;
        }

        var ptr = Marshal.SecureStringToBSTR(input);

        try
        {
            return Marshal.PtrToStringBSTR(ptr);
        }
        finally
        {
            Marshal.ZeroFreeBSTR(ptr);
        }
    }
}

以下內容非常簡單,假設您真的只想加密/解密字符串並將其存儲到磁盤。 請注意,這不使用密碼,它使用登錄用戶System.Security.Cryptography.DataProtectionScope.CurrentUser的安全上下文來保護數據。

public class SecureIt
{
    static byte[] entropy = System.Text.Encoding.Unicode.GetBytes("Salt Is Not A Password");

    public static string EncryptString(System.Security.SecureString input)
    {
        byte[] encryptedData = System.Security.Cryptography.ProtectedData.Protect(
            System.Text.Encoding.Unicode.GetBytes(ToInsecureString(input)),
            entropy,
            System.Security.Cryptography.DataProtectionScope.CurrentUser);
        return Convert.ToBase64String(encryptedData);
    }

    public static SecureString DecryptString(string encryptedData)
    {
        try
        {
            byte[] decryptedData = System.Security.Cryptography.ProtectedData.Unprotect(
                Convert.FromBase64String(encryptedData),
                entropy,
                System.Security.Cryptography.DataProtectionScope.CurrentUser);
            return ToSecureString(System.Text.Encoding.Unicode.GetString(decryptedData));
        }
        catch
        {
            return new SecureString();
        }
    }

    public static SecureString ToSecureString(string input)
    {
        SecureString secure = new SecureString();
        foreach (char c in input)
        {
            secure.AppendChar(c);
        }
        secure.MakeReadOnly();
        return secure;
    }

    public static string ToInsecureString(SecureString input)
    {
        string returnValue = string.Empty;
        IntPtr ptr = System.Runtime.InteropServices.Marshal.SecureStringToBSTR(input);
        try
        {
            returnValue = System.Runtime.InteropServices.Marshal.PtrToStringBSTR(ptr);
        }
        finally
        {
            System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(ptr);
        }
        return returnValue;
    }

}

然后加密一個字符串:

  var clearText = "Some string to encrypt";
  var cypherText = SecureIt.EncryptString( SecureIt.ToSecureString( clearText));

並隨后解密:

var clearText = SecureIt.ToInsecureString( SecureIt.DecryptString(cypherText));

出於我的目的,我修改Jesse C. Slicer解決方案以不使用SecureString因為保護內存對我來說並不重要。 我只需要序列化加密的字符串。 為了使這個工作項目需要引用System.Security (不僅僅是 using 語句)。

public static class StringSecurityHelper
{
    private static readonly byte[] entropy = Encoding.Unicode.GetBytes("5ID'&mc %sJo@lGtbi%n!G^ fiVn8 *tNh3eB %rDaVijn!.c b");

    public static string EncryptString(this string input)
    {
        if (input == null)
        {
            return null;
        }

        byte[] encryptedData = ProtectedData.Protect(Encoding.Unicode.GetBytes(input), entropy, DataProtectionScope.CurrentUser);

        return Convert.ToBase64String(encryptedData);
    }

    public static string DecryptString(this string encryptedData)
    {
        if (encryptedData == null)
        {
            return null;
        }

        try
        {
            byte[] decryptedData = ProtectedData.Unprotect(Convert.FromBase64String(encryptedData), entropy, DataProtectionScope.CurrentUser);

            return Encoding.Unicode.GetString(decryptedData);
        }
        catch
        {
            return null;
        }
    }
}

並使用它:

string cypherText = "My string".EncryptString();
string clearText = cypherText.DecryptString();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM