如何混淆本地存储的 user/password 以发送到第三方应用程序?

How to obfuscate locally stored user/password to be sent onward to 3rd party app?

场景:

问题:

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

混淆约束:

Jon Galloway's blog which is from 2008 but made me look into DPAPI: as I understand it, System.Security.Cryptography.ProtectedData with DataProtectionScope.CurrentUser 应禁止其他用户对密码进行去混淆处理。

问题:

我应该提供什么作为 entropy 值来禁用另一台机器上克隆的 User 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 会使混淆无效 - 因此混淆不是加密。我所追求的是一种更严格的“无法从文件中读取明文密码”的版本,第二个因素是“需要使用相同的 windows 用户登录”和“在同一台机器上”。

我还研究了 How should I ethically approach user password storage for later plaintext retrieval? 这并没有多大帮助,因为它的答案主要假设某种具有我没有的密码重置机制的网络场景。

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

https://www.harmj0y.net/blog/redteaming/operational-guidance-for-offensive-user-dpapi-abuse/ 表明只要您能够以任何方式或形式冒充用户,DPAPI 就有几个可利用的“缺陷”。

我结合了 ProtectData.Protect and it's counterpart ProtectData.Unprotect 将根据某些值 pertinent/different 计算出的熵添加到每个用户。

生成的字节流使用 DeflateStream 压缩并存储。

对于解码,我使用适当的函数反向执行类似的操作。

我知道:这充其量只是密码混淆,但目前它“已经足够好了”——而且比使用相同的 Crypto.dll 和固定的关键短语要好得多访问特定 windows account/pc 及其存储的秘密。