2010-03-08 2 views
3

Я пытаюсь использовать CredWrite, но получите ошибку ERROR_INVALID_PARAMETER 87 (0x57). Цель состоит в том, чтобы иметь безопасное место для сохранения пароля пользователя для моего .net-приложения WPF.Кто-нибудь использовал функцию Win32 API CredWrite в .NET?

И мой код:

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

Посмотрите здесь .... http://stackoverflow.com/questions/2337672/credwrite-returns-win32-error-code-2-error-invalid-function-incorrect-function/2337753#2337753 – t0mm13b

+1

Просто перечитайте код, и похоже, что класс Credential не сортируется (согласно комментарию) .... duh! :) – mlsteeves

+4

http://blogs.msdn.com/peerchan/pages/487834.aspx - У вас есть полное решение, и оно работает. – mlsteeves

ответ

3

Я столкнулся с этой же проблемой сейчас. Я обнаружил, что эта проблема возникла с использованием параметра DOMAIN_PASSWORD в качестве типа учетных данных. Оказалось, что TargetName содержит неправильное значение.

Вы должны указывать только адрес dns или ip (необязательный подстановочный знак), , но НЕ содержащий полный URL-адрес или протокол. , например. «* .microsoft.com» является правильным, но «http://www.microsoft.com/» является INVALID

Я просто отправлю это здесь, если другие люди столкнутся с этой проблемой. Мне потребовалось некоторое время, чтобы найти его.

+0

FYI: Ограничения при определении домена аналогичны ограничениям для функции OSX SecKeychainItemCreateFromContent, используемой для служб Keychain –

 Смежные вопросы

  • Нет связанных вопросов^_^