繁体   English   中英

如何尽可能安全地解密本地存储的密钥

[英]How to decrypt a locally stored key as secure as possible

我有一个需要在应用程序中使用的密钥。 该密钥必须以持久方式存储在设备上。 我需要在不使用用户密码之类的外部输入的情况下恢复此密钥。 需要网络/服务器连接的任何身份验证(除了使用Active Directory身份验证初始系统登录之外)对我来说都不可用。

现在,为了自己解密任何加密数据,我需要一个解密的私钥,该私钥必须再次存储在某个地方,我不确定此处的最佳做法。

在Windows 7中使用.NET来存储和解密所述密钥的最安全方法是什么?

您可以通过带有P / Invoke的CredReadCredWrite使用Credential Vault。 它特定于正在登录或模拟的用户,不需要密码即可解密。

这是我的一项部署任务中的一个示例,下面是一个如何安全地获取只能用于用户任务访问的模拟密码的示例。 可以通过control /name Microsoft.CredentialManager或通过cmdkey /?来设置cmdkey /? ,或通过CredWrite

private Task Impersonate()
{
    if (As == null)
        return this;
    Log.Debug("[As] {0}", As);

    IntPtr token;
    if (!CredRead(As, 1, 0, out token))
        throw new Win32Exception();

    var cred = (Credential)Marshal.PtrToStructure(token, typeof(Credential));
    CredFree(token);

    var name = cred.UserName.Split('\\');
    var user = new { Name = name[1], Domain = name[0], Password = Marshal.PtrToStringAuto(cred.CredentialBlob) };
    Log.Info("[As] {0}\\{1}", user.Domain, user.Name);

    if (!LogonUser(user.Name, user.Domain, user.Password, 9, 0, out token))
        throw new Win32Exception();

    Context = WindowsIdentity.Impersonate(token);

    if (!CloseHandle(token))
        throw new Win32Exception();

    return this;
}

[DllImport("advapi32", SetLastError = true)]
private static extern bool CredRead(string target, uint type, uint flags, out IntPtr credential);

[DllImport("advapi32", SetLastError = true)]
private static extern void CredFree(IntPtr buffer);

[DllImport("advapi32", SetLastError = true)]
private static extern bool LogonUser(string username, string domain, string password, int type, int provider, out IntPtr token);

[DllImport("kernel32", SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle);

private struct Credential
{
    #pragma warning disable 169, 649
    public uint Flags;
    public uint Type;
    public string TargetName;
    public string Comment;
    public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
    public uint CredentialBlobSize;
    public IntPtr CredentialBlob;
    public uint Persist;
    public uint AttributeCount;
    public IntPtr Attributes;
    public string TargetAlias;
    public string UserName;
    #pragma warning restore 169, 649
}

DPAPI应该可以帮助您透明地加密和解密密钥

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM