Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este artículo se proporciona información sobre cuándo usar marcas específicas al llamar a CryptAcquireContext y las razones para usar estas marcas.
Número de KB original: 238187
Resumen
Las llamadas a la CryptAcquireContext función pueden incluir varias marcas. Es importante saber cuándo usar estas marcas. En este artículo se proporciona información sobre cuándo usar marcas específicas al llamar CryptAcquireContext a y las razones para usar estas marcas.
Más información
No se realizan operaciones de clave privada
Cuando no usa una clave privada persistente, se puede usar la marca CRYPT_VERIFYCONTEXT (0xF0000000) cuando se llama a CryptAcquireContext. Esto indica a CryptoAPI que cree un contenedor de claves en la memoria que se liberará cuando se llame a CryptReleaseContext. Cuando se usa esta marca, el parámetro pszContainer debe ser NULL. La marca CRYPT_VERIFYCONTEXT se puede usar en los escenarios siguientes:
Va a crear un hash.
Está generando una clave simétrica para cifrar o descifrar datos.
Deriva una clave simétrica de un hash para cifrar o descifrar datos.
Está comprobando una firma. Es posible importar una clave pública desde publicKEYBLOB o desde un certificado mediante CryptImportKey o CryptImportPublicKeyInfo.
Tiene previsto exportar una clave simétrica, pero no importarla dentro de la duración del contexto criptográfico.
Nota:
Se puede adquirir un contexto mediante la marca CRYPT_VERIFYCONTEXT si solo tiene previsto importar la clave pública para los dos últimos escenarios.
Está realizando operaciones de clave privada, pero no usa una clave privada persistente que se almacena en un contenedor de claves.
Las operaciones de clave privada se realizan
Si planea realizar operaciones de clave privada, hay muchos problemas que debe tener en cuenta.
La mejor manera de adquirir un contexto es intentar abrir el contenedor. Si se produce un error en este intento con "NTE_BAD_KEYSET", cree el contenedor mediante la marca CRYPT_NEWKEYSET.
Nota:
Las aplicaciones no deben usar el contenedor de claves predeterminado pasando NULL para que el nombre del contenedor almacene claves privadas. Cuando varias aplicaciones usan el mismo contenedor, una aplicación puede cambiar o destruir las claves que otra aplicación necesita tener disponible. Si las aplicaciones usan contenedores de claves con un nombre único, se reduce el riesgo de que otras aplicaciones manipule las claves necesarias para una función adecuada.
// Acquire Context of container that is unique to each user.
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
0))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
// Error ...
}
}
}
// Or, acquire Context of container that is shared across the machine.
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
CRYPT_MACHINE_KEYSET))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET|CRYPT_MACHINE_KEYSET)
{
// Error ...
}
}
}
Uso de la marca CRYPT_MACHINE_KEYSET
Si no realiza operaciones de clave privada por usuario y necesita operaciones de clave privada global, se debe usar CRYPT_MACHINE_KEYSET. Este método crea el par de claves privadas o públicas por equipo. Algunos escenarios específicos en los que se deben usar CRYPT_MACHINE_KEYSET son:
- Está escribiendo un servicio.
- El componente se ejecuta en una página de páginas de Active Server (ASP).
- El componente es un componente de Microsoft Transaction Server (MTS). En estos ejemplos, se usa CRYPT_MACHINE_KEYSET porque el contexto de seguridad en el que se ejecuta la aplicación no tiene acceso a un perfil de usuario. Por ejemplo, un cliente MTS puede suplantar a un usuario, pero el perfil del usuario no está disponible porque el usuario no ha iniciado sesión. Lo mismo sucede con un componente que se ejecuta en una página ASP.
Proporcionar acceso al contenedor
De forma predeterminada, cuando se crea un contenedor de claves, el sistema local y el creador son los únicos usuarios que tienen acceso al contenedor. La excepción a esto es cuando un administrador crea el contenedor de claves. El sistema local y todos los demás administradores tendrán acceso al contenedor de claves. Cualquier otro contexto de seguridad no puede abrir el contenedor.
Si el código se ejecutará en más de un contexto de seguridad, debe conceder a los usuarios adecuados acceso al contenedor.
Para establecer la seguridad en el contenedor, llame a la función CryptSetProvParam con la marca PP_KEYSET_SEC_DESCR después de crear el contenedor. Este método permite establecer el descriptor de seguridad en el contenedor.
En el código siguiente se muestra cómo llamar a CryptSetProvParam. Esto se realiza inmediatamente después de la creación del contenedor de claves.
// Acquire Context
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
0))
{
if (GetLastError() == NTE_BAD_KEYSET)
{
if (!CryptAcquireContext(&hProv,
"Container",
NULL,
PROV_RSA_FULL,
CRYPT_NEWKEYSET))
{
// Error ...
}
// Create Security Descriptor (pSD)...
// Set the Security Descriptor on the container
if (!CryptSetProvParam(hProv,
PP_KEYSET_SEC_DESCR,
pSD,
DACL_SECURITY_INFORMATION))
{
// Error ...
}
}
}
Errores de CryptAcquireContext
A continuación se muestran los códigos de error más comunes y los posibles motivos del error.
- NTE_BAD_KEYSET (0x80090016)
- El contenedor de claves no existe.
- No tiene acceso al contenedor de claves.
- El servicio de almacenamiento protegido no se está ejecutando.
- NTE_EXISTS (0x8009000F)
- El contenedor de claves ya existe, pero está intentando crearlo. Si se produjo un error en un intento anterior de abrir la clave con NTE_BAD_KEYSET, implica que se deniega el acceso al contenedor de claves.
- NTE_KEYSET_NOT_DEF (0x80090019)
- Es posible que el proveedor de servicios criptográficos (CSP) no esté configurado correctamente. El uso de Regsvr32.exe en archivos DLL de CSP (Rsabase.dll o Rsaenh.dll) puede corregir el problema, en función del proveedor que se use.