Pergunta

I am porting an old VB6 application to .NET and I am having an issue since yesterday afternoon with some CryptoAPI calls.

In particular I can't retrieve a key container which is already defined. I use the CryptAcquireContext() function. I use some test code where I create the container. Then If I go to C:\Users...\Roaming\Microsoft\Crypto\RSA\Machine Keys\ I can see a file created with my defined container name inside so I assume it's created successfully.

A subsequent call to try creating the same container verifies that assumption because I get the win32 error that the keyset is already defined.

Anyway on my next code call where I try to retrieve the container I already created I get the windows error that the keyset is not defined.

Error : -2146893799 (80090019) The keyset is not defined.

Any ideas?

Here's a code example :

public const uint PROV_RSA_FULL = 1;
public const uint CRYPT_NEWKEYSET = 0x00000008;
public const uint CRYPT_MACHINE_KEYSET = 0x00000020;
const string MS_DEF_PROV = "Microsoft Base Cryptographic Provider v1.0";

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptAcquireContext(out IntPtr phProv, string pszContainer, string pszProvider, uint dwProvType, uint dwFlags);

public static void CreateContainer()
{
        IntPtr hCryptProv;
        int error;
        if (!CryptAcquireContext(out hCryptProv, "new", MS_DEF_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET))
        {
            error = Marshal.GetLastWin32Error();
        }

        if (!CryptAcquireContext(out hCryptProv, "new", MS_DEF_PROV, PROV_RSA_FULL, CRYPT_MACHINE_KEYSET))
        {
            error = Marshal.GetLastWin32Error();
        }
}
Foi útil?

Solução

You are creating key container for that user, but trying to get it from machine-based storage. To fix the problem you need either change CRYPT_MACHINE_KEYSET to 0 or when creating keyset use CRYPT_NEWKEYSET | CRYPT_MACHINE_KEYSET according to your needs.

By default, keys and key containers are stored as user keys. For Base Providers, this means that user key containers are stored in the user's profile. A key container created without this flag by an administrator can be accessed only by the user creating the key container and a user with administration privileges.

For details, please check the links below.

CryptAcquireContext() use and troubleshooting

CryptAcquireContext function

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top