Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何混淆本地存储的用户/密码以发送至第三方应用程序?_C#_Windows_Password Encryption - Fatal编程技术网

C# 如何混淆本地存储的用户/密码以发送至第三方应用程序?

C# 如何混淆本地存储的用户/密码以发送至第三方应用程序?,c#,windows,password-encryption,C#,Windows,Password Encryption,场景: 用户A登录Windows(8以上,服务器2008R2以上) 用户通过带有用户名和密码的软件访问第三方服务 我需要提供“保持登录”体验,因此我需要一个对称的模糊PW本地存储密码(特定于用户-在%localappdata%/软件/…)中) 问题: 到目前为止,我的前任使用带有密码块链接和硬编码摘要的符号Rijndael来混淆密码。任何获得复制的%localappdata%文件的用户和任何maschine都可以使用用户A存储的凭据成功进行身份验证。我不喜欢 模糊处理约束: 我想以某种方式

场景:

  • 用户A登录Windows(8以上,服务器2008R2以上)
  • 用户通过带有用户名和密码的软件访问第三方服务
  • 我需要提供“保持登录”体验,因此我需要一个对称的模糊PW本地存储密码(特定于用户-在%localappdata%/软件/…)中)
问题:

到目前为止,我的前任使用带有密码块链接和硬编码摘要的符号Rijndael来混淆密码。任何获得复制的%localappdata%文件的用户和任何maschine都可以使用用户A存储的凭据成功进行身份验证。我不喜欢

模糊处理约束:

  • 我想以某种方式将密码混淆与登录的windows用户/maschine联系起来
  • 更改f.e.windows用户密码不应使模糊密码无效
  • 将文件移动到(克隆的)用户a所在的另一台主机上会使DeobFousation无效
  • 将文件从用户A移动到用户B应使DeobFousation无效
这是从2008年开始的,但让我思考:据我所知,with应该禁止其他用户对密码进行非自定义

问题:

我应该提供什么作为熵值来禁用克隆用户a在不同主机上的访问,还是应该完全使用其他路径


使用字符串密码短语测试MSDN中ProtectedData内容的一些代码:

// modified from https://docs.microsoft.com/de-de/dotnet/api/system.security.cryptography.protecteddata
using System;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

public class DataProtectionSample
{
  static string GetHexString (byte [] data)
    => string.Join (" ", data.Select (d => d.ToString ("x2")));

  static string GetUnicodeString (byte [] data)
    => Encoding.Unicode.GetString (data);

  static byte [] GetBytesFromUnicode (string data)
    => Encoding.Unicode.GetBytes (data);

  public static void Main ()
  {
    // Create byte array for additional entropy when using Protect method.
    byte [] entropy = { 9, 8, 7, 6, 5 };
    byte [] secret = GetBytesFromUnicode ("Cräzy obfuscated paß phrâse");

    //Encrypt the data.
    byte [] encryptedSecret = Protect( secret , entropy );

    Console.WriteLine ("The encrypted byte array is:");
    Console.WriteLine (GetHexString (encryptedSecret));

    // Decrypt the data and store in a byte array.
    byte [] originalData = Unprotect( encryptedSecret, entropy );
    Console.WriteLine ("{0}The original data is:", Environment.NewLine);
    Console.WriteLine (GetUnicodeString (originalData));

    Console.ReadLine ();
  }

  static byte [] Protect (byte [] data, byte [] entropy)
  {
    try
    {
      return ProtectedData.Protect (data, entropy, DataProtectionScope.CurrentUser);
    }
    catch (CryptographicException e)
    {
      Console.WriteLine (e.ToString ());
      return null;
    }
  }

  static byte [] Unprotect (byte [] data, byte [] entropy)
  {
    try
    {
      return ProtectedData.Unprotect (data, entropy, DataProtectionScope.CurrentUser);
    }
    catch (CryptographicException e)
    {
      Console.WriteLine (e.ToString());
      return null;
    }
  }
}

我知道模拟用户A会使混淆无效-因此混淆不是加密。我所追求的是一种更严格的版本“无法从文件中读取明文pw”,第二个因素是“需要使用同一个windows用户登录”和“在同一台机器上”

我还研究了wich并没有太大的帮助,因为它的答案大多假设了某种带有密码重置机制的web场景,而我没有这种机制

免责声明:我的密码是随机生成的Keypass存储值。我不使用“保持登录”功能。以明文存储密码是邪恶的,存储对称加密的密码可能会被破坏,必须避免。仍然需要提供上述功能


表明只要您能够以任何方式或形式模拟用户,DPAPI就有几个可利用的“缺陷” 它的对应项是加入一个熵,该熵是根据与每个用户相关/不同的一些值计算出来的

生成的ByTestStream使用压缩和存储

对于解码,我使用适当的函数做类似的事情


我知道:这充其量只是密码混淆,但现在它“足够好了”-这比使用相同的Crypto.dll和固定的密钥短语要好得多,这些密钥短语适用于没有访问特定windows帐户/pc及其存储机密的所有人。

您不需要更改熵-不同的用户即使使用相同的熵数据也无法解密帐户是否具有管理员权限?如果他们这样做,那么数据保护范围对你没有任何好处。@charles也许。为什么作为一名本地管理员会对此产生任何影响?如果以管理员身份登录,我仍然不是同一个用户,无法
ProtectedData。取消保护
其他一些用户存储的数据?@PatrickArtner管理员可以在会话0、会话0中创建服务,或者
系统
帐户可以模拟任何用户。例如,使用
PsExec
,我可以在计算机的任何用户下生成一个进程。因此,我非常确定,如果使用im admin,只有在当前用户上下文下运行的线程才能取消数据保护。另外,会话0中的程序可以轻松读取内存。或者,作为管理员,您可以获取文件和文件夹的所有权。作为服务,您可以使用
WTSQueryUserToken
获取用户令牌,然后使用
CreateProcessAsUser
在您选择的用户下生成一个进程。