我正在尝试使用CredWrite
,但收到ERROR_INVALID_PARAMETER 87 (0x57)
错误。目的是为我的.net WPF应用程序保存用户密码的安全位置。
我的代码:
public class CredMan
{
private const string TARGET_PREFIX = "myappname:";
public static void SavePassword(string username, string password)
{
Win32CredMan.Credential cred = new Win32CredMan.Credential();
cred.Flags = 0;
cred.Type = Win32CredMan.CRED_TYPE.GENERIC;
cred.TargetName = TARGET_PREFIX + username;
var encoding = new System.Text.UTF8Encoding();
cred.CredentialBlob = encoding.GetBytes(password);
cred.Persist = Win32CredMan.CRED_PERSIST.LOCAL_MACHINE;
cred.UserName = username;
bool isGood = Win32CredMan.CredWrite(cred, 0);
int lastError = Marshal.GetLastWin32Error();
}
}
这是win32包装器:(主要是从pinvoke.net抓取的)
internal class Win32CredMan
{
[DllImport("Advapi32.dll", EntryPoint = "CredReadW", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern bool CredRead(string target, CRED_TYPE type, int reservedFlag,
[MarshalAs(UnmanagedType.CustomMarshaler, MarshalTypeRef = typeof(CredentialInMarshaler))]out Credential credential);
[DllImport("Advapi32.dll", EntryPoint = "CredFreeW", CharSet = CharSet.Unicode, SetLastError = true)]
public static extern void CredFree(IntPtr buffer);
[DllImport("Advapi32.dll", SetLastError = true, EntryPoint = "CredWriteW", CharSet = CharSet.Unicode)]
public static extern bool CredWrite([In] Credential userCredential, [In] UInt32 flags);
public enum CRED_TYPE : uint
{
GENERIC = 1,
DOMAIN_PASSWORD = 2,
DOMAIN_CERTIFICATE = 3,
DOMAIN_VISIBLE_PASSWORD = 4,
GENERIC_CERTIFICATE = 5,
DOMAIN_EXTENDED = 6,
MAXIMUM = 7, // Maximum supported cred type
MAXIMUM_EX = (MAXIMUM + 1000), // Allow new applications to run on old OSes
}
public enum CRED_PERSIST : uint
{
SESSION = 1,
LOCAL_MACHINE = 2,
ENTERPRISE = 3,
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct CREDENTIAL_ATTRIBUTE
{
string Keyword;
uint Flags;
uint ValueSize;
IntPtr Value;
}
//This type is deliberately not designed to be marshalled.
public class Credential
{
public UInt32 Flags;
public CRED_TYPE Type;
public string TargetName;
public string Comment;
public System.Runtime.InteropServices.ComTypes.FILETIME LastWritten;
public byte[] CredentialBlob;
public CRED_PERSIST Persist;
public CREDENTIAL_ATTRIBUTE[] Attributes;
public string TargetAlias;
public string UserName;
}
}
答案 0 :(得分:3)
我现在遇到了同样的问题。 我发现使用DOMAIN_PASSWORD选项作为凭据类型发生此问题。 事实证明TargetName包含不正确的值。
你应该只指定dns或ip地址(通配符可选), 但不包含完整的URL或协议。 例如“* .microsoft.com”是正确的,但“http://www.microsoft.com/”是无效的
我会在这里发布此内容以防其他人遇到此问题。我花了一段时间才找到它。