【问题标题】:NetworkCredentials exposes password in plain textNetworkCredentials 以纯文本形式公开密码
【发布时间】:2015-12-20 19:10:12
【问题描述】:

我即将在我的 C#/WPF 应用程序中创建一个身份验证模块。为了对用户进行身份验证,我想使用 NetworkCredential 来存储凭据。

Credential = new NetworkCredential(credential.UserName, credential.Password);

其中credential.UserNamestringcredential.PasswordSecureString 类型。在调试应用程序时,我可以看到纯文本和安全字符串中的密码

为什么密码显示为纯文本?这不是可能的安全威胁吗?

感谢您的回答。

编辑:

作为记录,NetworkCredential 对象应在 WCF 客户端上使用,如下所示:

client.ClientCredentials.Windows.ClientCredential = Credentials

【问题讨论】:

  • 这不是可能的安全威胁吗?如果您正在调试,您可以在运行时检查它吗?您可以在运行时使用附加的调试器执行大多数操作。
  • @JayMee 我认为关键是因为NetworkCredential 在构造函数中采用了SecureString,所以它不应该立即将其作为纯文本属性公开给它自己,以及任何其他人看着。 “感谢您将这些安全信息传递给我。大家好,看看这个!”
  • @JayMee 不,我是说NetworkCredential 不应该采用SecureString,获取它的价值并将其作为普通String 公开。如果要这样做,传递SecureString 有什么意义?我也是——我只是(希望如此!)稍微澄清一下这个问题......
  • @JayMee 问题是,为什么会有SecureString SecurePasswordstring Password。如果您可以从Password 获得其实际值,SecurePassword 似乎不太安全。这是违反直觉的。
  • @sab669,因为 Password 属性是代码而不是数据。数据包嗅探器检查数据,但不执行代码;确实在数据包中没有密码属性/代码供嗅探器执行,只有数据,并且密码属性不在数据包数据中。

标签: c# .net


【解决方案1】:

NetworkCredential 内部类 always stores the password 作为 SecureString

 public string Password {
        get {
            ExceptionHelper.UnmanagedPermission.Demand();
            return InternalGetPassword();
        }
        set {
            m_password = UnsafeNclNativeMethods.SecureStringHelper.CreateSecureString(value);
        }
    }

当有人需要以纯文本形式检索密码时(在某些时候需要,无论是从这个类中还是在链中更远的地方),它retrieves it from the secure string

    internal string InternalGetPassword() {
        string decryptedString = UnsafeNclNativeMethods.SecureStringHelper.CreateString(m_password);
        return decryptedString;
    }

使用调试器时,它显示属性,因此从SecureString检索值

【讨论】:

    【解决方案2】:

    SecureString与加密无关! (严重的过度简化 - 可能它也是加密的,但这在这里并不是那么重要;如果你从普通的 string 创建一个 SecureString,你已经否定了 @ 的大量收益987654324@ - 短期)

    它只是一个可以确定地释放的字符串。出于安全原因,这一点很重要,因为 .NET 字符串的寿命可能很长(对于实习字符串,是应用程序的整个生命周期)。

    NetworkCredential 不用于存储凭据 - 它只是一个简单的旅行车,可以将它们带到他们要去的地方 - 基本上是一个通用 API。

    【讨论】:

    • 但是,为什么只有一个类将 SecureString 作为构造函数参数(“嘿,你可以相信我”),然后将其公开为普通的 String
    • @JamesThorpe 为什么不呢?您有 SecureString 属性来获取安全字符串。大多数 API 没有为您提供任何使用 SecureString 的方法。这是一个选择加入的功能,真的。 string 是在您查询Password 属性 时按需创建的。
    • 我知道SecureString 与加密无关,但为什么NetworkCredential 将我的密码公开为纯文本?这不会将密码作为纯文本存储在内存中吗?
    • @JamesThorpe Password 是一个属性。仅当您明确要求时才会创建该字符串 - 当然,调试器倾向于查询被监视对象的所有属性。在您请求转换之前,该字符串不存在于内存中。
    • @TobiasMoeThorstensen 它只是为您提供了一种将密码读取为字符串的方法。如果您这样做,并继续使用SecureString 属性,则不存在“违规”。 Password 属性仅用于不支持 SecureString 的 API。
    猜你喜欢
    • 2017-01-27
    • 2013-10-18
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 2016-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多