transporte tipos simplex resueltos operaciones modelos metodos metodo matriz logistica investigacion ejercicios definicion c windows encryption cryptography mscapi

c - tipos - metodos de transporte pdf



Microsoft Crypto API desactiva el uso del algoritmo de transporte de claves RSAES-OAEP (1)

El Key Transport Algorithm es un poco difícil de manejar, y puede no cumplir su propósito (veo que notó que le gustaría que CAPI admita RSAencryption , RSAencryption , yo también). Parece que ya ha detectado la mayor parte de su problema: el mensaje generado es válido, pero su método hace que sea necesario usar CryptEncryptMessage , que no funcionará bien / en absoluto en el largo plazo.

Paso 1 - Examina el código

CRYPT_ENCRYPT_MESSAGE_PARA EncryptMessageParams; EncryptMessageParams.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO); EncryptMessageParams.dwMsgEncodingType = PKCS_7_ASN_ENCODING; EncryptMessageParams.ContentEncryptionAlgorithm.pszObjId = szOID_NIST_AES256_CBC; EncryptMessageParams.ContentEncryptionAlgorithm.Parameters.cbData = 0; EncryptMessageParams.ContentEncryptionAlgorithm.Parameters.pbData = 0; EncryptMessageParams.hCryptProv = NULL; EncryptMessageParams.pvEncryptionAuxInfo = NULL; EncryptMessageParams.dwFlags = 0; EncryptMessageParams.dwInnerContentType = 0; BYTE pbEncryptedBlob[640000]; DWORD pcbEncryptedBlob = 640000; BOOL retval = CryptEncryptMessage(&EncryptMessageParams, cRecipientCert, pRecipCertContextArray, pbMsgText, dwMsgTextSize, pbEncryptedBlob, &pcbEncryptedBlob);

Bastante básico, ¿no? Aunque eficiente, en realidad no se está solucionando el problema. Si miras esto:

EncryptMessageParams.dwFlags = 0; EncryptMessageParams.dwInnerContentType = 0;

verá que está predefinido, pero se usa solo en la definición de retval . Sin embargo, definitivamente podría ver esto como una micro-optimización, y no es realmente útil si vamos a volver a escribir el código. Sin embargo, describí los pasos básicos para integrar esto sin una repetición total del código (para que pueda seguir usando los mismos parámetros):

Paso 2 - Editando los parámetros

Como @owlstead mencionó en sus comentarios, Crypto API no es muy fácil de usar. Sin embargo, has hecho un gran trabajo con recursos limitados. Lo que querrá agregar es un Proveedor de Enumeración Criptográfica para ayudar a reducir las claves. Asegúrese de tener Microsoft Base Cryptographic Provider versión 1.0 o Microsoft Enhanced Cryptographic Provider versión 1.0 para usarlos de manera eficiente. De lo contrario, deberá agregar la función de la siguiente manera:

DWORD cbName; DWORD dwType; DWORD dwIndex; CHAR *pszName = NULL; (regular crypt calls here)

Esto se usa principalmente para evitar el error NTE_BAD_FLAGS , aunque técnicamente se puede evitar esto con una declaración de bajo nivel. Si lo desea, también puede crear un hash completamente nuevo (aunque esto solo es necesario si la implementación anterior no se escalará al factor necesario de tiempo / velocidad):

DWORD dwBufferLen = strlen((char *)pbBuffer)+1*(0+5); HCRYPTHASH hHash; HCRYPTKEY hKey; HCRYPTKEY hPubKey; BYTE *pbKeyBlob; BYTE *pbSignature; DWORD dwSigLen; DWORD dwBlobLen; (use hash as normal w/ crypt calls and the pbKeyBlobs/Signatures)

Asegúrese de actualizar este fragmento antes de continuar. Puedes hacerlo fácilmente así:

if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_FULL, 0)) { printf("CSP context acquired./n"); }

Si está documentando o liberando, es posible que desee agregar un void MyHandleError(char *s) para detectar el error, de modo que alguien que edite pero falle pueda atraparlo rápidamente.

Por cierto, la primera vez que lo ejecute tendrá que crear un nuevo conjunto porque no hay ningún valor predeterminado. Un buen trazador de líneas que puede aparecer en un if está a continuación:

CryptAcquireContext(&hCryptProv, NULL, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)

Recuerde que la sincronización de los recursos del servidor no será tan eficiente como hacer el re-trabajo que sugerí en el primer paso. Esto es lo que explicaré a continuación:

Paso 3: recodificar y reiniciar

Como programador, la redecodificación puede parecer una pérdida de tiempo, pero definitivamente puede ayudarte en el largo plazo. Recuerde que aún tendrá que codificar en los parámetros personalizados cuando codifique / sincronice; No voy a darte de comer a mano todo el código como un bebé. Debería ser suficiente para mostrarle los contornos básicos.

Definitivamente estoy asumiendo que estás intentando manejar el contenedor de claves del usuario actual dentro de un CSP en particular ; de lo contrario, realmente no veo el uso de esto. Si no, puede hacer algunas ediciones básicas para satisfacer sus necesidades.

Recuerde, vamos a omitir CryptEncryptMessage utilizando CryptReleaseContext , que libera directamente el identificador adquirido por la función CryptAcquireContext . El estándar de Microsoft en el CAC está a continuación:

BOOL WINAPI CryptAcquireContext( _Out_ HCRYPTPROV *phProv, _In_ LPCTSTR pszContainer, _In_ LPCTSTR pszProvider, _In_ DWORD dwProvType, _In_ DWORD dwFlags );

Tenga en cuenta que Microsoft le regaña si usa una interfaz de usuario:

Si el CSP debe mostrar la IU para operar, la llamada falla y el código de error NTE_SILENT_CONTEXT se establece como el último error. Además, si las llamadas se realizan a CryptGenKey con el indicador CRYPT_USER_PROTECTED con un contexto que se ha adquirido con el indicador CRYPT_SILENT, las llamadas fallan y el CSP establece NTE_SILENT_CONTEXT.

Este es principalmente el código del servidor, y ERROR_BUSY definitivamente se mostrará a los nuevos usuarios cuando haya múltiples conexiones, especialmente aquellas con una alta latencia. Por encima de NTE_BAD_KEYSET_PARAM solo se NTE_BAD_KEYSET_PARAM a NTE_BAD_KEYSET_PARAM o similar, debido al tiempo de espera sin que se reciba un error adecuado. (Problemas de transmisión, ¿alguien conmigo?)

A menos que le preocupen las múltiples DLL (que no son compatibles debido a los errores de NTE_PROVIDER_DLL_FAIL ), la configuración básica para tomar los servicios crypt en el lado del cliente sería la siguiente (copiada directamente de los ejemplos de Microsoft):

if (GetLastError() == NTE_BAD_KEYSET) { if(CryptAcquireContext( &hCryptProv, UserName, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { printf("A new key container has been created./n"); } else { printf("Could not create a new key container./n"); exit(1); } } else { printf("A cryptographic service handle could not be " "acquired./n"); exit(1); }

Por simple que parezca, definitivamente no quiere quedarse atascado pasando esto al algoritmo de intercambio de claves (o lo que sea que tenga que manejar esto). A menos que esté utilizando claves de sesión simétricas (Diffie-Hellman / KEA), el par de claves de intercambio se puede usar para encriptar claves de sesión para que puedan ser almacenadas e intercambiadas de manera segura con otros usuarios.

Alguien llamado John Howard ha escrito una buena Utilidad de Configuración de Administración Remota de Hyper-V (HVRemote), que es una gran compilación de las técnicas discutidas aquí. Además de utilizar las criptas y los cscript hvremote.wsf básicos, se pueden usar para permitir el acceso DCOM remoto ANONYMOUS LOGON ( cscript hvremote.wsf , para ser específico). Puedes ver muchas de las funciones y técnicas en sus últimas criptas (tendrás que restringir la consulta) en su blog:

http://blogs.technet.com/b/jhoward/

Si necesita más ayuda con los conceptos básicos, simplemente deje un comentario o solicite un chat privado.

Conclusión

Aunque es bastante simple una vez que te das cuenta de los métodos básicos del servidor para hash y cómo el cliente toma las "criptas", estarás cuestionando por qué incluso probaste el cifrado durante las transmisiones. Sin embargo, sin la criptación del cliente, el cifrado definitivamente sería la única forma segura de transmitir lo que ya fue hasheado.

Aunque podría argumentar que los paquetes podrían descifrarse y eliminarse las sales, tenga en cuenta que tanto en la salida como en la salida deberían procesarse y almacenarse en el momento y el orden correctos necesarios para volver a codificar el cliente.

Estoy usando CryptEncryptMessage para generar un mensaje envuelto PKCS#7 . Estoy usando szOID_NIST_AES256_CBC como el algoritmo de encriptación.

El mensaje generado parece ser válido, pero es el RSAES-OAEP para Key Transport Algorithm, que tiene un soporte limitado en la naturaleza (Thunderbird, OpenSSL SMIME Module entre muchos otros no lo admiten).

Me gustaría que CAPI volviera a la antigua RSAencryption para el transporte de claves.

¿Hay alguna manera posible de hacerlo, podría volver a las funciones de mensajes de bajo nivel si hay una forma en lugar de utilizar CryptEncryptMessage pero no puedo encontrar una manera de hacerlo incluso con las funciones de bajo nivel.

Código:

CRYPT_ENCRYPT_MESSAGE_PARA EncryptMessageParams; EncryptMessageParams.cbSize = sizeof(CMSG_ENVELOPED_ENCODE_INFO); EncryptMessageParams.dwMsgEncodingType = PKCS_7_ASN_ENCODING; EncryptMessageParams.ContentEncryptionAlgorithm.pszObjId = szOID_NIST_AES256_CBC; EncryptMessageParams.ContentEncryptionAlgorithm.Parameters.cbData = 0; EncryptMessageParams.ContentEncryptionAlgorithm.Parameters.pbData = 0; EncryptMessageParams.hCryptProv = NULL; EncryptMessageParams.pvEncryptionAuxInfo = NULL; EncryptMessageParams.dwFlags = 0; EncryptMessageParams.dwInnerContentType = 0; BYTE pbEncryptedBlob[640000]; DWORD pcbEncryptedBlob = 640000; BOOL retval = CryptEncryptMessage(&EncryptMessageParams, cRecipientCert, pRecipCertContextArray, pbMsgText, dwMsgTextSize, pbEncryptedBlob, &pcbEncryptedBlob);