Procedimientos de creación, almacenamiento, y utilización de los

Anuncio
Procedimientos de creación,
almacenamiento, y utilización de los
componentes criptográficos de los
certificados de entidad final
Esta especificación ha sido preparada por
ANF AC para liberar a terceras partes.
NIVEL DE SEGURIDAD
DOCUMENTO PÚBLICO
Este documento es propiedad de ANF Autoridad de Certificación.
Está prohibida su reproducción y difusión sin autorización expresa
de ANF Autoridad de Certificación
-Copyright © ANF Autoridad de Certificación
ÍNDICE
1. Introducción ............................................................................... 3
2. Características técnicas de la librería utilizada ................................. 4
2.1 Arquitectura .................................................................................... 4
2.2
Interface ....................................................................................... 5
2.3. Manejo de los objetos criptográficos .................................................. 6
3. Análisis de los procedimientos ....................................................... 7
3.1 Calidad del material criptográfico ....................................................... 7
3.2 Aleatoriedad .................................................................................... 9
3.3 Generación de claves ...................................................................... 11
3.3.1 Claves RSA ................................................................................. 12
3.3.2 Claves de sesión .......................................................................... 15
3.4 Almacenamiento de material sensible ............................................... 17
3.5 Inicialización y cierre ...................................................................... 17
3.6 Gestión de errores ......................................................................... 18
3.7 Proceso de generación de petición de certificado................................. 19
3.8 Importación de certificados ............................................................. 21
3.9 Proceso de firma ............................................................................ 22
3.10 Proceso de verificación .................................................................. 24
4. Consideraciones adicionales ........................................................ 26
5. Referencias .............................................................................. 27
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
2 de 27
1. Introducción
En primer lugar cabe reseñar que ANF AC, tal y como consta en la Declaración de
Practicas de Certificación, genera certificados raíz y certificados de CA intermedios
para su actividad como prestador de servicios de certificación. Los certificados raíz
solo son utilizados para generar los certificados de CA intermedios, y su uso
requiere una autorización expresa de la Junta de Gobierno de ANF Autoridad de
Certificación.
Un manual completo de procedimientos de utilización de módulos criptográficos
requeriría una descripción detallada de los algoritmos criptográficos utilizados por
los mismos. En este caso, sin embargo, se ha seguido la máxima, que se suele
repetir de forma recurrente en el mundo de la seguridad informática, de utilizar
procedimientos e implementaciones de reconocido prestigio y cuyo contenido haya
sido sometido a una supervisión pública.
Ese planteamiento se ha traducido en la utilización de algoritmos criptográficos
abiertos RSA. Estos algoritmos cumplen los planteamientos expuestos
anteriormente.
Por otro lado, y como se verá posteriormente en el apartado de análisis, los
algoritmos criptográficos, los formatos y los protocolos y procedimientos de
intercambio, almacenamiento y gestión de claves y certificados siguen los
estándares internacionales más extendidos.
El enfoque que se va a seguir en este documento de los procedimientos seguidos
por ANF AC en el desarrollo de sus dispositivos de certificación raíz e intermedios,
hace especial énfasis en asegurar el material sensible, habiendo creado un entorno
de programación “estanco”. Dos zonas de programación con equipos de ingeniería
sin posibilidad de contacto entre sí. Uno, formado por especialistas en criptografía,
dedicado a la elaboración y el mantenimiento de la librería criptográfica y el
segundo, construyendo el interfaz de usuario. Se comprobará que se ha respetado
ese enfoque y que se hace una utilización eficiente del interfaz, así como que se es
consciente del funcionamiento interno de la misma y que la configuración de
parámetros que se utiliza es correcta.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
3 de 27
2. Características técnicas de la librería
utilizada
Como característica fundamental de la librería implementada se puede destacar que
ofrece una interfaz de utilización al programador de MUY ALTO NIVEL, lo que
resulta de vital importancia para que los riesgos que corre un programador al
utilizar la librería se ven muy minimizados, en cuanto a que no dispone de la
capacidad de interactuar con los objetos criptográficos a bajo nivel, si no es a
través de la interfaz suministrada.
Además, en dicho interfaz no se gestiona directamente material criptográfico (lo
cual permitiría realizar operaciones externas saltándonos los controles de la
misma). En lugar de eso, la única interacción que proporciona se basa en utilizar
representaciones de alto nivel, unos “objetos criptográficos” manejados
simplemente por medio de un ID (un handler) a partir del cual no es posible
obtener externamente la información criptográfica asociada, puesto que ésta la
oculta la propia arquitectura de la librería.
2.1 Arquitectura
La mayoría de las librerías de programación criptográficas permiten interactuar con
el material criptográfico a varios niveles. Sin embargo, en el caso de la librería
utilizada por ANF AC, se restringe el acceso tanto a la información sensible como a
las propias funciones de tratamiento.
Para ello, plantea un sistema de kernel seguro estructurado en capas, de modo que
se ocultan las funciones de tratamiento específico asociadas a cada algoritmo de
firma, generación de claves, etc. proporcionando una interfaz que únicamente deja
disponible ciertas funcionalidades.
Así, la capa superior, la que se presenta al programador, se basa en modelar
cualquier elemento criptográfico de forma genérica por medio de un conjunto
mínimo de objetos, traducidos en tipos de datos. Como se ha comentado, esos
objetos se utilizan en base a handlers, con lo que en ningún caso se dispone de una
estructura de datos accesible directamente en memoria.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
4 de 27
Figura 1.- Tipos básicos
La arquitectura emplea un kernel seguro para implementar los mecanismos de
control de acceso al material sensible. Así, dicho kernel es el que proporciona la
interfaz entre el exterior (representado a través de los handlers) y las estructuras
de datos que maneja internamente la librería. Así se consiguen varios objetivos:
Por un lado, aislar los algoritmos del resto de la implementación dificultando una
posible manipulación de los mismos. Además permite unificar las funciones de
procesamiento de alto nivel, que son independientes del algoritmo, procedimiento,
modo de cifrado, etc.…
2.2
Interface
El hecho de que las operaciones sobre los objetos criptográficos se realicen de
forma independiente del algoritmo o procedimiento concreto que se desea utilizar,
hace que el interfaz de utilización sea muy sencillo. Así, a la hora de realizar
cualquier operación sobre un objeto criptográfico, basta con establecer si se desea
los atributos (como longitud de la clave, algoritmo a utilizar, modo de cifrado,
etc.…) e invocar a una función genérica.
CRYPT_CONTEXT
privKeyContext;
cryptCreateContext(
&privKeyContext,
cryptUser,
CRYPT_ALGO_RSA
);
cryptSetAttributeString( privKeyContext, CRYPT_CTXINFO_LABEL, label,
labelLength ); cryptGenerateKey( privKeyContext );
Figura 2.- Ejemplo básico de generación de claves RSA en un contexto.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
5 de 27
De hecho, la utilización de objetos avanzados como los envelopes o las sessions,
hace que se abstraigan incluso las operaciones de cifrado/descifrado, que se
gestionan internamente por la librería.
La utilización de una API independiente del algoritmo hace que la utilización
nuevos algoritmos o variaciones de los mismos sea prácticamente transparente,
cuanto a que el programador únicamente debe modificar el ID del algoritmo,
atributo asociado al objeto que maneja, manteniendo el resto de la lógica de
programa.
de
en
un
su
Por otro lado, la propia librería realiza comprobaciones continuas que impiden que
se utilice un objeto criptográfico para operaciones para las cuales no estaba
pensado (como cifrar con claves destinadas sólo a firmar, utilizar certificados
inválidos, etc…), e incluso valida que los algoritmos estén funcionando
correctamente. Este modo de operación hace que el trabajo del programador esté
muy dirigido, restringiendo los grados de libertad de éste. Esto, unido a la
ocultación de las estructuras de datos que maneja la librería minimiza la posibilidad
de que el programador cometa errores tanto de simple programación, como lo que
podríamos llamar “conceptuales” (asociados a un posible desconocimiento de los
fundamentos de las operaciones criptográficas a realizar).
2.3. Manejo de los objetos criptográficos
La gestión de los objetos criptográficos tiene dos variantes. Por un lado, desde el
punto de vista del programador, el manejo se limita a la utilización de los objetos
de alto nivel descritos en puntos anteriores.
Cuando se invoca a cualquier función de la API de alto nivel, la librería realiza una
serie de comprobaciones de permisos de acceso basadas en dos tipos de ACLs, así
como comprobaciones de la coherencia. Esto es, además de comprobar que el rol
del usuario que desea realizar una operación le permite realizarla, comprueba que
la operación no viola el perímetro de seguridad que establece la librería (que no
trata por ejemplo de acceder a material privado). Por último comprueba que el tipo
y atributos del objeto(s) a utilizar, así como el de la operación a realizar son
compatibles y soportan dicha operación.
El sistema contempla que se requiera la presencia de varios operadores para que
sea posible utilizar los objetos criptográficos.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
6 de 27
3. Análisis de los procedimientos
3.1 Calidad del material criptográfico
La calidad del material criptográfico se fundamenta, por un lado, en que la
implementación de los algoritmos se ha realizado respetando los estándares más
restrictivos, así como implementaciones de referencia (algunos procedimientos
están basados por ejemplo en la famosa SSLeay de Eric Young, base también de la
actual OpenSSL).
Algoritmo
Implmentación
Blowfish
Implementación basada en "Description of a New Variable-Length
Key, 64-bit Block Cipher (Blowfish)", Bruce Schneier, "Fast
Software Encryption", Lecture Notes in Computer Science No. 809,
Springer-Verlag 1994
CAST-128
Modos de operación según la norma ISO/IEC 8372, "Information
Technology -Modes of Operation for a 64¬bit Block Cipher
Algorithm".
DES
Implementación basada RFC 2144, "The CAST-128 Encryption
Algorithm", Carlisle Adams, May 1997
Triple DES
Implementación basada en las normas ANSI X3.92, "American
National Standard, Data Encryption Algorithm", 1981; FIPS PUB 462, "Data Encryption Standard", 1994; FIPS PUB 74, "Guidelines for
Implementing and Using the NBS Data Encryption Standard", 1981;
ISO/IEC 8731:1987, "Banking -Approved Algorithms for Message
Authentication - Part 1: Data Encryption Algorithm (DEA)".
DiffieHellman
Modos de operación basados en ANSI X3.106, "American National
Standard, Information Systems - Data Encryption Algorithm Modes of Operation", 1983.; FIPS PUB 81, "DES Modes of
Operation", 1980.; ISO/IEC 8372, "Information Technology - Modes
of Operation for a 64-bit Block Cipher Algorithm".
DSA
Implementación basada en ANSI X9.17, "American National
Standard, Financial Institution Key Management (Wholesale)",
1985.;
ISO/IEC
8732:1987,
"Banking
-Key
Management
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
7 de 27
(Wholesale)".
HMAC-MD5
Modos de operación basados en ISO/IEC 8372, "Information
Technology - Modes of Operation for a 64-bit Block Cipher
Algorithm".
HMAC-SHA1
Implementación basada en el estándar PKCS #3, "Diffie-Hellman
Key Agreement Standard", 1991.
IDEA
Implementación basada en las normas ANSI X9.30-1, "American
National Standard, Public-Key Cryptography Using Irreversible
Algorithms for the Financial Services Industry", 1993.; FIPS PUB
186, "Digital Signature Standard", 1994.
MD5
Implementación basada en el estándar RFC 2104, "HMAC: KeyedHashing for Message Authentication", Hugo Krawczyk, Mihir Bellare,
and Ran Canetti, February 1997.
RSA
Implementación basada en el estándar RFC 2104, "HMAC: KeyedHashing for Message Authentication", Hugo Krawczyk, Mihir Bellare,
and Ran Canetti, February 1997.
RC5
Implementación según las siguientes referencias "Device for the
Conversion of a Digital Block and the Use Thereof", James Massey
and Xuejia Lai, International
Patent PCT/CH91/00117,1991. ;
"Device for the Conversion of a Digital Block and Use of Same",
James Massey and Xuejia Lai, US Patent #5,214,703, 1993.; "On
the Design and Security of Block Ciphers", Xuejia Lai, ETH Series in
Information Processing, Vol.1, Hartung-Gorre Verlag, 1992.;
ISO/IEC 9979, "Data Cryptographic Tecniques -Procedures for the
Registration of Cryptographic Algorithms".
SHA1
Modos de operación según SO/IEC 8372, "Information Technology Modes of Operation for a 64-bit Block Cipher Algorithm"
Tabla 1.- Recopilación de modelos de implementación de los protocolos.
En general la librería, según el autor Peter Guttman, se ha implementado de
acuerdo a un nivel 1 del estándar FIPS PUB 140-1, "Security Requirements for
Cryptographic Modules", 1993. En cuanto a los rutinas de adquisición de números
aleatorios, siguen los principios recogidos en "Randomness Recommendations for
Security", RFC 1750, Donald Eastlake, Stephen Crocker, and Jeffrey Schiller,
December 1994 y "Cryptographic Random Numbers", IEEE P1363 Appendix E, Draft
version 1.0, 11 November 1995.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
8 de 27
Por último, sobre el resultado de las operaciones anteriores de recolección de
entropía también se realiza un post-procesamiento con un generador X9.17
A esto, se le une que las configuraciones por defecto de la librería son muy
restrictivas, como se analizará en el apartado de generación de claves.
Con la aplicación de los métodos mencionados se puede estar seguro de que la
generación de los números aleatorios y las medidas de protección que se han
tomado en la confección de la librería son adecuadas para la solución de ANF AC.
3.2 Aleatoriedad
La propia librería incorpora un sistema seguro de “generación” de datos aleatorios
que posteriormente utiliza para crear claves de sesión, pares de claves
pública/privada así como en otras operaciones criptográficas.
La aleatoriedad se garantiza, además de por el propio algoritmo de generación, por
varios mecanismos:
•
La librería es capaz de utilizar dispositivos hardware de generación de
números aleatorio.
•
Por otro lado, aprovecha las capacidades que pueda proporcionar el sistema
operativo a la hora de crear números aleatorios. Por ejemplo, en el caso de
sistemas Unix, esta posibilidad se traduce en utilizar el dispositivo /dev/random,
que acumula continuamente datos aleatorios del sistema.
•
Añadido a los procedimientos anteriores, que se utilizan como fuente inicial
de números aleatorios, la propia librería va incorporando eventos aleatorios para
mejorar la calidad de la fuente aleatoria (como número de ficheros abiertos, estado
del sistema, ID de procesador, tamaño de la ventana…). Este proceso se realiza a
través de dos funciones slowPoll() y fastPoll() que el programador puede utilizar
explícitamente para introducir más o menos aleatoriedad, con mayor o menor coste
computacional. Por otro lado, antes de realizar cualquier procedimiento que
requiera datos aleatorios de calidad, la propia librería invoca dichas funciones
automáticamente (concretamente la más “aleatoria”, slowPoll()), sin intervención
del programador. En la Figura 3 se presenta un extracto de la función fastPoll() del
archivo fuente misc/rndwin32.c, donde se muestran los eventos que utiliza para
incorporar al flujo de datos aleatorios (a modo de semilla continua).
•
Por último, sobre el resultado de las operaciones anteriores de recolección
de entropía se realiza un post-procesamiento mediante un generador X9.17 [5]. En
la Figura 4 se observa un extracto del archivo dev/dev_sys.c donde se puede
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
9 de 27
observar la definición de número de ciclos X917_MAX_CYCLES que realiza el
generador X9.17 sobre los datos aleatorios con los que se ha alimentado
inicialmente el pool de datos aleatorios.
/* Check whether the CPU supports extended features like CPUID and
RDTSC, and get any info we need related to this. There is an
IsProcessorFeaturePresent() function, but all that this provides
_asm { ... [código en ensamblador para obtener información] }
/* If there's a vendor ID present, check for vendor-specific special
features */ if( hasAdvFeatures && !memcmp( vendorID, "CentaurHauls",
12 ) )
{ _asm { noRNG:
...} } }
/* If there's a hardware RNG present, read data from it. We check that
the RNG is still present on each fetch since it could (at least in pack,
since chars don't need alignment it would have no effect on the BYTE []
member */
addRandomValue(
randomState,
GetActiveWindow()
);
addRandomValue( randomState, GetCapture() ); addRandomValue(
randomState, GetClipboardOwner() ); ... ... addRandomValue(
randomState, GetInputState() ); addRandomValue( randomState,
GetProcessWindowStation()
);
addRandomValue(
randomState,
GetTickCount() ); handle = GetCurrentThread(); GetThreadTimes(
handle, &creationTime, &exitTime, &kernelTime, &userTime );
addRandomData( randomState, &creationTime, sizeof( FILETIME ) );
addRandomData( randomState, &exitTime, sizeof( FILETIME ) ); ...
handle
=
GetCurrentProcess();
GetProcessTimes(
handle,
&creationTime, &exitTime, &kernelTime, &userTime );
...*/
if( hasHardwareRNG
dispositivo]
)
...[código
de
lectura
de
información
del
Figura 3.- Generación de números aleatorios fastPoll()
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
10 de
27
/* The size in bytes of the randomness pool and the size of the X9.17
post-processor generator pool */
#define RANDOMPOOL_SIZE 256 #define X917_POOLSIZE 8
/* The allocated size of the randomness pool, which allows for the
overflow created by the fact that the hash function blocksize isn't any
useful multiple of a power of 2 */
#define RANDOMPOOL_ALLOCSIZE ( ( ( RANDOMPOOL_SIZE + 20 -1 ) /
20 ) * 20 )
/* In order to avoid the pool startup problem (where initial pool data
may consist of minimally-mixed entropy samples) we require that the
pool be mixed at least the following number of times before we can
draw data from it. This usually happens automatically because a slow
poll adds enough data to cause many mixing iterations, however if this
doesn't happen we manually mix it the appropriate number of times to
get it up to the correct level */
#define RANDOMPOOL_MIXES 10
/* The number of samples of previous output that we keep for the FIPS
140 continuous tests, and the number of retries we perform if we detect
a repeat of a previous output */
#define RANDOMPOOL_SAMPLES 16 #define RANDOMPOOL_RETRIES 5
/* The number of times that we cycle the X9.17 generator before we
load new key and state variables. This means that we re-seed for every
X917_MAX_BYTES of output produced */
#define X917_MAX_BYTES 8192 #define
X917_MAX_BYTES / X917_POOLSIZE )
X917_MAX_CYCLES
(
Figura 4.- Postprocesamiento con generador X9.17
3.3 Generación de claves
La generación de claves es otro aspecto básico a tener en cuenta a la hora de
evaluar el desarrollo de cualquier módulo criptográfico.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
11 de
27
Los aspectos de longitud de clave, modos de operación y demás se configuran por
medio de las funciones de gestión de atributos cryptSetAttribute() y
cryptSetAttributeString().
Para la generación de claves privadas se utilizan los contextos propios de la librería.
Cabe destacar que en el código por seguridad siempre se destruye el contexto tras
la utilización de una clave privada.
3.3.1 Claves RSA
El sistema de firma digital RSA basa su seguridad en la hipótesis de que el único
método efectivo de ataque es la factorización de su módulo que se elige como un
número entero grande, y en que esta operación de factorización es
computacionalmente imposible a partir de un tamaño de los números elegidos, y
dada una determinada potencia de cómputo para el presunto atacante. Así pues, el
criptosistema RSA requiere generar su módulo multiplicando dos números primos,
de tamaños semejantes y que cumplan ciertas restricciones. Para la generación de
esos números primos se utilizan algoritmos probabilísticas que afirman, con cierto
grado de certeza, que un determinado número puede ser primo.
El procedimiento de generación de claves se basa en la búsqueda de números
primos muy grandes (su longitud está relacionada directamente con la longitud del
par de claves a generar, por simplificar la mitad de dicha longitud).
Por tanto, el factor crítico en la generación de claves RSA es la variabilidad o
calidad de los números primos que se buscan durante el proceso de construcción de
la clave. Es por tanto de vital importancia que el proceso de búsqueda de dichos
números no sea fácilmente reproducible.
Para ello los procedimientos que sigue la librería son los recogidos en los siguientes
extractos de código,
/* Generate an RSA key pair into an encryption context */
int generateRSAkey( CONTEXT_INFO *contextInfoPtr,
keySizeBits ) { [INICIALIZACIÓN DE VARIABLES]
const
int
/* Determine how many bits to give to each of p and q */ pBits = (
keySizeBits + 1 ) / 2; qBits = keySizeBits -pBits; pkcInfo->keySizeBits
= pBits + qBits;
/* Generate the primes p and q and set them up so that the CRT
decrypt
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
12 de
27
will
work
*/
BN_set_word(
&pkcInfo->rsaParam_e,
RSA_PUBLIC_EXPONENT ); status = generatePrime( pkcInfo, p, pBits,
RSA_PUBLIC_EXPONENT,
contextInfoPtr ); if( cryptStatusOK( status ) ) status = generatePrime(
pkcInfo, q, qBits, RSA_PUBLIC_EXPONENT, contextInfoPtr ); if(
cryptStatusOK( status ) ) status = fixCRTvalues( pkcInfo, FALSE ); if(
cryptStatusError( status ) ) return( status );
/* Compute d = eInv mod (p -1)(q -1), e1 = d mod (p -1), and
e2 =d mod(q-1) */ CK( BN_sub_word( p, 1 ) ); CK( BN_sub_word( q, 1
) ); CK( BN_mul( tmp, p, q, &pkcInfo->bnCTX ) ); CKPTR(
BN_mod_inverse( d, &pkcInfo->rsaParam_e, tmp, &pkcInfo->bnCTX )
); CK( BN_mod( &pkcInfo->rsaParam_exponent1, d,
p, &pkcInfo->bnCTX ) ); CK( BN_mod( &pkcInfo->rsaParam_exponent2,
d, q, &pkcInfo->bnCTX ) ); CK( BN_add_word( p, 1 ) ); CK(
BN_add_word( q, 1 ) ); if( bnStatusError( bnStatus ) )
return( getBnStatus( bnStatus ) );
/* Compute n = pq, and u = qInv mod p */ CK( BN_mul( &pkcInfo>rsaParam_n, p, q, &pkcInfo->bnCTX ) ); CKPTR( BN_mod_inverse(
&pkcInfo->rsaParam_u, q, p, &pkcInfo->bnCTX ) ); if( bnStatusError(
bnStatus ) )
return( getBnStatus( bnStatus ) );
/* Evaluate the Montgomery forms */ return( getRSAMontgomery(
pkcInfo, FALSE ) ); }
Figura 5.- Función generateRSAkey ()
La función más importante para evaluar la calidad de la clave generada es, por
tanto, generatePrime().
static int generatePrime( PKC_INFO *pkcInfo, BIGNUM *candidate,
const int noBits, const long exponent, const void *callbackArg )
{ [INICIALIZACIÓN] /* Start with a cryptographically strong odd
random number */ status = generateBignum( candidate, noBits, 0xC0,
0x1 );
...
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
13 de
27
do { /* Set up the sieve array for the number and pick a random
starting
point */ initSieve( sieveArray, candidate ); setMessageData( &msgData,
&startPoint,
sizeof(
int
)
);
status
=
krnlSendMessage(
SYSTEM_OBJECT_HANDLE,
IMESSAGE_GETATTRIBUTE_S, &msgData, CRYPT_IATTRIBUTE_RANDOM
); if( cryptStatusError( status ) ) break; startPoint &= SIEVE_SIZE -1;
/* Perform a random-probing search for a prime. Poli, poli, di umbuendo
*/ for( offset = nextEntry( startPoint ); offset != startPoint;
offset = nextEntry( offset ) ) { long remainder;
/* If this candidate is divisible by anything, continue */ if( sieveArray[
offset ] ) continue;
/* Adjust the candidate by the number of nonprimes we've skipped */
if( offset > oldOffset ) CK( BN_add_word( candidate, ( offset -oldOffset )
* 2 ) ); else CK( BN_sub_word( candidate, ( oldOffset -offset ) * 2 ) );
oldOffset = offset;
status = primeProbable( pkcInfo, candidate, noChecks, callbackArg ); if(
cryptStatusError( status ) ) break; if( !status ) continue;
/* It's for use with RSA, check the RSA condition that gcd( p -1, exp )
== 1. Since exp is a small prime, we can do this efficiently by checking
that ( p -1 ) mod exp != 0 */
CK( BN_sub_word( candidate, 1 ) ); remainder = BN_mod_word(
candidate, exponent ); CK( BN_add_word( candidate, 1 ) ); if(
bnStatusOK( bnStatus ) && remainder )
break; /* status = TRUE from above */ } } while( status == FALSE ); /*
-ve = error, TRUE = success */
[DEVUELVE RESULTADO]
Figura 6.- Función generatePrime ()
Del código anterior se han eliminado secciones correspondientes a la comprobación
del test.
En el caso de la librería empleada, el método utilizado es el test Millar-Rabin
seguido de un test de Fermat. La elección de los algoritmos es correcta y su
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
14 de
27
implementación es eficaz, pero su seguridad depende del número de veces que se
realiza el test de Millar-Rabín antes de aceptar un número como probable primo.
En la implementación de la librería este número de iteraciones se elige en función
de la longitud del número primo que se quiere localizar, y se ajusta de modo que la
probabilidad de no ser realmente primo sea de 2-80; es decir, de un fallo entre
1024 casos. Dado que el Test de Fermat tiene una posibilidad de 10-44 de no
reconocer a un número de 512 bits como compuesto cuando lo es, por lo que el uso
combinado de ambos algoritmos es muy recomendable.
A la vista de estos valores, se puede estar seguro de la calidad, en cuanto a su
factorización, de los módulos RSA que genera la librería. La combinación de esto
con la colección de algoritmos utilizados para generación de números aleatorios,
permite afirmar que la generación de claves RSA por parte de la mencionada
librería los hace válidos para ser utilizados en sistemas de Firma Electrónica
Avanzada.
La elección de longitudes de clave de 2.048 bits para la firma de los certificados raíz
e intermedios es correcta actualmente y posiblemente sea así en los próximos cinco
o siete años.
3.3.2 Claves de sesión
En el caso de querer derivar claves de sesión a partir de cierta información secreta,
bien sea ésta una passphrase o material criptográfico intercambiado previamente,
el parámetro a controlar es el número de iteraciones que realizar el algoritmo de
generación de la clave a partir de dicha información inicial.
Por defecto el proceso de generación de claves realizará repetidamente una
operación HASH con la función HMAC-SHA1 sobre un SALT de entrada y la
información secreta.
Ese proceso de hash se repite 16.000 veces para dificultar posibles ataques de
adivinación de contraseña.
Ese parámetro se controla a partir del atributo del CRYPT_CONTEXT denominado
CRYPT_CTXINFO_KEYING_ITERATIONS, de la forma que sigue:
cryptSetAttribute( cryptContext, CRYPT_CTXINFO_KEYING_ITERATIONS, 1000 );
Para comprobar que el número de iteraciones por defecto es de
16.000 se muestra un extracto del código correspondiente a la inicialización de la
librería,
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
15 de
27
fixedOptionInfo[] = { /* Dummy entry for CRYPT_ATTRIBUTE_NONE */
{ CRYPT_ATTRIBUTE_NONE, 0 },
/* cryptlib information (read-only) */
{
CRYPT_OPTION_INFO_DESCRIPTION,
CRYPT_UNUSED, "cryptlib security toolkit" },
OPTION_STRING,
{
CRYPT_OPTION_INFO_COPYRIGHT,
OPTION_STRING,
CRYPT_UNUSED, "Copyright Peter Gutmann, Eric Young, OpenSSL,
1994-2004" },
{
CRYPT_OPTION_INFO_MAJORVERSION,
CRYPT_UNUSED, NULL, 3 },
OPTION_NUMERIC,
{
CRYPT_OPTION_INFO_MINORVERSION,
CRYPT_UNUSED, NULL, 1 },
OPTION_NUMERIC,
{
CRYPT_OPTION_INFO_STEPPING,
CRYPT_UNUSED, NULL, 0 },
OPTION_NUMERIC,
/* Context options, base = 0 */ /* Algorithm = Conventional
encryption/hash/MAC options */ { CRYPT_OPTION_ENCR_ALGO,
OPTION_NUMERIC,
0,
NULL,
CRYPT_ALGO_3DES
},
{
CRYPT_OPTION_ENCR_HASH,
OPTION_NUMERIC,
1,
NULL,
CRYPT_ALGO_SHA }, { CRYPT_OPTION_ENCR_MAC, OPTION_NUMERIC,
2, NULL, CRYPT_ALGO_HMAC_SHA },
/* Algorithm = PKC options */ { CRYPT_OPTION_PKC_ALGO,
OPTION_NUMERIC,
3,
NULL,
CRYPT_ALGO_RSA
},
{
CRYPT_OPTION_PKC_KEYSIZE,
OPTION_NUMERIC,
4,
NULL,
bitsToBytes( 1024 ) },
/* Algorithm = Signature options */ { CRYPT_OPTION_SIG_ALGO,
OPTION_NUMERIC,
5,
NULL,
CRYPT_ALGO_RSA
},
{
CRYPT_OPTION_SIG_KEYSIZE,
OPTION_NUMERIC,
6,
NULL,
bitsToBytes( 1024 ) },
/*
Algorithm
=
Key
CRYPT_OPTION_KEYING_ALGO,
CRYPT_ALGO_SHA },
derivation
options
OPTION_NUMERIC,
7,
*/
{
NULL,
{ CRYPT_OPTION_KEYING_ITERATIONS, OPTION_NUMERIC, 8, NULL,
16000 },
/* Certificate options, base = 100 */
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
16 de
27
{
CRYPT_OPTION_CERT_SIGNUNRECOGNISEDATTRIBUTES,
OPTION_BOOLEAN, 100, NULL, FALSE },
{ CRYPT_OPTION_CERT_VALIDITY, OPTION_NUMERIC, 101, NULL, 365
},
{ CRYPT_OPTION_CERT_UPDATEINTERVAL,
NULL, 90 },
OPTION_NUMERIC,
102,
{ CRYPT_OPTION_CERT_COMPLIANCELEVEL, OPTION_NUMERIC, 103,
NULL, CRYPT_COMPLIANCELEVEL_STANDARD },
/* CMS options */ { CRYPT_OPTION_CMS_DEFAULTATTRIBUTES,
OPTION_BOOLEAN, 104, NULL, TRUE },
Figura 7.- Configuración del número de iteraciones
3.4 Almacenamiento de material sensible
El almacenamiento del material sensible se realiza sobre objetos denominados
CRYPT_KEYSETs.
Para el almacenamiento en disco se utiliza un KEYSET de tipo FILE. La librería no
utiliza el formato más común, PKCS#12, por considerarlo poco seguro. Ni siquiera
permite la opción de exportar material privado a ese formato.
En lugar de eso utiliza PKCS#15, un formato mucho más robusto.
3.5 Inicialización y cierre
En la inicialización del software del cliente se procede a realizar las siguientes
tareas en orden:
1. Se inicializa la librería mediante la función cryptInit(), que inicializa todos los
estados internos de la misma y se realizan una serie de comprobaciones. También
carga una configuración por defecto.
2-Se modifican una serie de parámetros de configuración de la librería en lo
concerniente a los algoritmos de firma y hash utilizados por defecto como
preferidos.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
17 de
27
En concreto se escoge como algoritmo de firma el RSA y la longitud por defecto de
clave de 1024 bits. Como algoritmo de hash se utiliza por defecto el SHA2.
3-Importación del certificado raíz de la Autoridad de Certificación. Dicho certificado
se encuentra incorporado dentro del código a través de un array binario y se
importa
como
objeto
de
la
librería
libcrypt
a
través
de:
EVAL(cryptImportCert(certData, length, CRYPT_UNUSED, &cert)); Posteriormente
se habilita el atributo de trusted para que la librería confíe en él. Con este
procedimiento evitamos el riesgo que puede tener que alguien nos cambie el
certificado raíz si lo leyéramos de fichero.
4-Se abre un keyset donde se almacenan las claves privadas generadas por el
usuario, así como los certificados asociados. El formato del keyset es un fichero
PKCS#15 manejado de forma nativa y transparente por la librería. Con este
keystore se trabajará a la largo del programa.
Durante el correcto funcionamiento del programa se hacen las llamadas
correspondientes a la librería utilizando la interfaz de alto nivel que ofrece la mayor
protección frente a fallos o descuidos del programador.
El procedimiento de cierre puede producirse por cierre normal del programa (a
petición del usuario), por una condición de error o por una señalización externa
(generalmente por parte del sistema operativo). En cualquier caso se procede a una
salida ordenada del mismo cerrando el keystore y cerrando la librería mediante
cryptEnd().
3.6 Gestión de errores
En todo el programa se realiza un control de errores exhaustivo, y muy
especialmente en lo relacionado con la interacción con la librería criptográfica.
Siempre se comprueba el error y se retorna de la función que esté realizando el
procesamiento si se detecta un código de error en una llamada a una función de la
librería. Para ellos se encapsulan todas las llamadas a la librería mediante una
macro EVAL(), como en el siguiente ejemplo:
EVAL(cryptAddPublicKey(keyset, cert));
El tratamiento del error corresponderá a la función de nivel superior, que deberá
decidir sobre la gravedad del error y tomar la acción pertinente como
comunicárselo al usuario y continuar el programa o simplemente finalizar el
programa.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
18 de
27
3.7 Proceso de generación de petición de certificado
El proceso de generación de certificado implica la generación de un par de claves
privadas. En la implementación actual se utiliza el algoritmo RSA con una longitud
de clave de 1024 bits para los certificados de usuario.
Los pasos seguidos en la generación de petición al certificado implican utilizar la
interfaz de alto nivel de la librería de acuerdo a las recomendaciones del autor.
Se utiliza un keyset donde se almacenan los pares de claves de usuario. El keyset
empleado es un archivo PKCS#15. Dicho archivo tiene una limitación implícita
impuesta por la librería de un máximo de 32 claves, cantidad más que suficiente
para un único usuario. El keyset se abre poco después de la inicialización de la
librería y se cierra al finalizar el programa normal o anormalmente, tal y como se
describe en el punto sobre inicialización y cierre del programa. El siguiente
fragmento de código explica el proceso de generación de petición de certificado:
int status;
/* Generating key-pair with algorithm type specified */
EVAL(cryptCreateContext(keyPair, CRYPT_UNUSED, algoType));
EVAL(cryptSetAttributeString(*keyPair,
keyLabel, \
CRYPT_CTXINFO_LABEL,
keyLabelLength));
EVAL(cryptGenerateKey(*keyPair));
EVAL(cryptCreateCert(certReq,
CRYPT_CERTTYPE_CERTREQUEST));
CRYPT_UNUSED,
/* Only public key is effectively added though we pass the key pair */
EVAL(cryptSetAttribute(*certReq,
CRYPT_CERTINFO_SUBJECTPUBLICKEYINFO, *keyPair));
if(!addCertFields(*certReq, certData))
return(FALSE);
/* Sign cert */
EVAL(cryptSignCert(*certReq, *keyPair));
/* Check cert. It is self signed so it does not need anything else */
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
19 de
27
EVAL(cryptCheckCert(*certReq, CRYPT_UNUSED));
Figura 9.- Proceso de generación de la petición de certificado
Como puede observarse los pasos son:
1- Crear un contexto para generar el par de claves privadas mediante la función
cryptCreateContext().
2- Generar el par de claves mediante cryptGenerateKey()
3- Crear un objeto certificado del tipo CRYPT_CERTTYPE_REQUEST.
4- Adjuntar la clave
(cryptSetAttribute).
privada
a
la
petición
de
certificado
como
atributo
5- Rellenar los campos de la petición del certificado a partir de la entrada realizada
por los operadores autorizados y que chequearán el formato especificado en la CPS
de ANF AC .
6- Firmar la petición del certificado con la clave privada recién creada
(cryptCertSign).
El certificado se exporta a un fichero y posteriormente la clave privada es troceada
y almacenada en diferentes partes: una de las partes es cifrada y se almacena en el
keystore con passwords proporcionados por los operadores autorizados, el resto de
los trozos de la clave se almacena en el keystore de cada dispositivo de firma de
cada operador autorizado, y a su vez cada keystore es cifrado con el password
privado de cada respectivo operador, de tal forma que para hacer uso de la clave
privada es preciso:
1.- que
dispositivos,
estén
presentes
todos
los
operadores
con
sus
respectivos
2.- que los operadores activen sus dispositivos con su respectivo PIN
secreto,
3.- que tengan acceso al contenedor donde esta almacenado la parte
general de la clave, y que los operadores introduzcan los PIN secreto que permiten
su descifrado, y siguiendo el orden establecido para el descifrado por capas.
Las comprobaciones sobre el password son las siguientes:
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
20 de
27
1- No se permiten passwords sin combinaciones de números y letras
(tiene que haber caracteres de ambos tipos)
2- La longitud mínima es de 8 caracteres
3- Se compara el password con una base de datos o diccionario de
passwords “comunes” no autorizados.
Una vez comprobado el password se almacena la clave privada en el
keystore a través de la función cryptAddPrivateKey(). La librería contiene una clave
de alta seguridad, esta clave esta troceada y cada trozo esta dentro de la API
criptográfica, y alguno de los trozos se obtiene por aplicación de un algoritmo
determinista. La clave seleccionada por el operador es cifrada con esta clave de alta
seguridad, y el producto resultante es utilizado como password para cifrar la clave
privada. Después se destruye el objeto de contexto que contiene la pareja de
claves en memoria, mediante cryptDestroyContext(). De esta forma se garantiza
que ni tan siquiera el operador conoce la clave de cifrado, y es preciso utilizar la
API licenciada para procesar el sistema.
Después de destruir el contexto de cifrado también se borra (sobrescribiendo con
otro valor) la zona de memoria donde se almacena el password de usuario para
minimizar ataques por acceso a la zona de memoria del proceso aprovechando
vulnerabilidades del sistema operativo.
Si se trata de un certificado de CA intermedia, la petición de certificado se guarda
en formato PKCS#10, y ese certificado de petición es firmado con la clave privada
del certificado raíz a cuya jerarquía va a estar sometido.
3.8 Importación de certificados
La importación de certificados de CA intermedios se realiza una vez que ha pasado
el proceso administrativo de expedición del certificado por parte de la CA. En este
proceso se determina el número de operadores que tiene que estar presente para
activar la clave privada asociada a ese certificado.
La aplicación parte del certificado en un fichero, se admiten los dos tipos de
codificación estándar para ficheros de certificado: PEM (base 64) o DER (binario).
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
21 de
27
La aplicación lee y envía el fichero a un buffer realizando la conversión pertinente a
formato binario si se encuentra en codificación Base64. Una vez tenemos el
certificado en un buffer de datos se importa mediante la función cryptImportCert().
Una vez importado el certificado sin error se adjunta al keystore donde deberá
residir la clave privada correspondiente, utilizando la función cryptAddPublicKey().
En caso de no encontrarse una clave privada asociada la función producirá un error
y se abortará el proceso.
La propia librería no deja asociar a un keystore con claves privadas certificados que
no estén asociados a ninguna clave privada.
3.9 Proceso de firma
En el procedimiento de firma, la API solicita del operador o del sistema, la
localización del archivo a firmar, así como la localización del fichero firmado.
A continuación se consulta el keystore para localizar los certificados del usuario. Se
le presenta una lista con todos los disponibles. Se le indica al mismo que escoja
uno.
Se chequea el certificado para verificar que es correcto, no ha caducado y no se
encuentra revocado. La lista de certificados revocados se obtiene de un fichero
firmado por la CA que puede estar disponible bien localmente o bien remotamente.
La opción depende y es responsabilidad del usuario.
Posteriormente se accede a la clave privada asociada del certificado, para lo cuál se
precisa de los passwords que lo protegen. A continuación se le solicita el password
de la clave privada y se accede a la misma a través de la función
cryptGetPrivateKey(). Se comprueba el error para verificar si no existe la clave o
simplemente el usuario ha especificado una clave incorrecta ofreciéndole varios
intentos más.
La función devuelve un manejador de objeto CRYPT_CONTEXT, que contiene la
clave privada.
A continuación se siguen una serie de pasos que pueden esquematizarse con este
fragmento de código:
CRYPT_ENVELOPE env;
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
22 de
27
/* Signing and hashing algorithms should be set in configuration */
EVAL(cryptCreateEnvelope(&env,
CRYPT_FORMAT_CRYPTLIB));
CRYPT_UNUSED,
EVAL(cryptSetAttribute(env, CRYPT_ENVINFO_SIGNATURE, signKey));
EVAL(cryptSetAttribute(env, CRYPT_ENVINFO_DATASIZE, dataLength));
EVAL(cryptPushData(env, data, dataLength, &bytesCopied));
EVAL(cryptFlushData(env));
if(bytesCopied < dataLength)
{
const int initialBytesIn = bytesCopied;
EVAL(cryptPushData(env, (BYTE *) data + initialBytesIn, \
dataLength - initialBytesIn, &bytesCopied ));
bytesCopied += initialBytesIn;
}
if(bytesCopied != dataLength) {
return ERROR_DATACOPY
}
EVAL(cryptPopData(env,
&bytesCopied));
signedData,
signedDataBufferSize,
Figura 8.- Proceso de firma digital
Pueden observarse una serie de pasos. Se crea un objeto de tipo CRYPT_ENVELOPE
que es la interfaz de alto nivel que ofrece la librería para “alterar” datos de forma
local. Se aplica para los procedimientos de firma, verificación, cifrado y descifrado
de datos. Este objeto conoce el tipo de manipulación que van a sufrir los datos que
pasen a través de él por los objetos que se le añadan como atributos. En este caso
puede observarse que le pasamos el objeto signKey de tipo CRYPT_CONTEXT, que
es la clave privada que acabamos de recuperar del keystore, para maximizar la
eficiencia del proceso también le pasamos como atributo la longitud de los datos
que le vamos a pasar para firmar.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
23 de
27
De esta forma la librería reserva un buffer adecuado para el procesamiento que se
va a llevar a cabo y puede realizar todo el procesamiento de una vez.
Después le pasamos los datos del fichero a firmar (ya en forma de buffer) a través
de la función cryptPushData(). Como puede observarse se realiza la comprobación
de que efectivamente se copian todos los datos a la hora de firmar y no quedan
datos fuera.
Una vez terminado el paso anterior se recuperan los datos firmados a través de la
función cryptPopData(). Posteriormente se exportan estos datos a un fichero.
Cabe mencionar en este apartado que el algoritmo que escoge la librería para
generar el hash de la firma es el especificado por el parámetro de configuración
CRYPT_OPTION_ENCR_HASH que ya nos hemos asegurado al comienzo del
programa a fijar a SHA2. El algoritmo para cifrar el hash viene condicionado por el
tipo de clave privada que usemos que ya hemos especificado anteriormente que es
de tipo RSA.
La firma resultante se exporta a un fichero en formato deseado por el operador, en
la ruta indicada por el usuario.
3.10 Proceso de verificación
El proceso de verificación es análogo al proceso de firma. Lo único indicar en este
caso que no es preciso indicar el certificado ya que va incluido en la firma que llega
en un fichero en formato deseado por el firmante.
En este caso se solicita del operador que indique dónde se encuentra el fichero de
firma y opcionalmente la ruta de salida para obtener el documento sin firmar en
caso de que lo requiera el operador.
El procedimiento es el siguiente:
CRYPT_ENVELOPE env;
/* Signature contains everything to check it (cert chain, algorithms,
etc.) */
EVAL(cryptCreateEnvelope(&env,
CRYPT_FORMAT_CRYPTLIB));
Componentes
criptográficos
entidad final
de ANF AC
CRYPT_UNUSED,
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
24 de
27
EVAL(cryptSetAttribute(env,
signedDataLength));
EVAL(cryptPushData(env,
&bytesCopied));
CRYPT_ENVINFO_DATASIZE,
signedData,
signedDataLength,
EVAL(cryptFlushData(env));
if(bytesCopied < signedDataLength)
{
const int initialBytesIn = bytesCopied;
EVAL(cryptPushData( env, (BYTE *) signedData + initialBytesIn, \
signedDataLength - initialBytesIn, &bytesCopied ));
bytesCopied += initialBytesIn;
}
if(bytesCopied != signedDataLength) {
return ERROR_DATACOPY
}
EVAL(cryptPopData(env, (int *)data, dataBufferSize, &bytesCopied));
Figura 12.- Proceso de verificación de firma digital
Como puede verse en este caso se crea un objeto CRYPT_ENVELOPE y se le añade
el atributo del tamaño de los datos firmados. En este caso el objeto sabe que tiene
que verificar la firma cuando se le pasan los datos de firma a través de
cryptPushData(), previamente importados del fichero proporcionado por el
operador.
Cabe destacar que los certificados generados mediante esta librería contienen
atributos concretos que los identifican ante otros certificados (ver CPS de ANF AC).
Los dispositivos de firma solo pueden utilizar certificados que integran estos
atributos y que han sido emitidos por ANF AC.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
25 de
27
4. Consideraciones adicionales
Existe una serie de consideraciones adicionales relativas a la seguridad del entorno
de firma. La principal de ellas es poder determinar que la librería criptográfica que
utilizamos es realmente la original y que no es realmente otra librería que la
suplanta para filtrar las comunicaciones con la misma.
Uno de los métodos aplicados es el de realizar una operación de hash sobre la
propia librería determinando la que realmente está cargada a través de llamadas al
sistema, y compararlo con el valor adecuado almacenado dentro del programa. Esta
opción sin duda es bastante versátil pero no resuelve algunas de las problemáticas
como puede ser la necesidad de generar el hash de forma externa a la librería,
abandonando por consiguiente el entorno óptimo para la generación del mismo.
La solución adoptada ha sido, si cabe, más sencilla, pero más efectiva. Se trata de
enlazar estáticamente la librería al programa. Algo que puede resultar poco
eficiente en un principio, pero que no lo es tanto cuando existen otro tipo de
requerimientos de mayor importancia, como es este caso, o los recursos
disponibles en un entorno operativo medio son más que sobrados para esta
solución, como la cantidad de memoria disponible o espacio en HD.
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
26 de
27
5. Referencias
[1] Recomendación para la certificación de componentes destinados a la emisión y
gestión de certificados. Annabelle Lee, NIST; et. al. Estudio promovido por la NSA.
“Certificate Issuing and Management Components Family of Protection Profiles
Version 1.0”
Disponible en:
http://csrc.nist.gov/ pki/documents/CIMC_PP_final-corrections_20010126.pdf
[2] Normas europeas de estandarización CWA 14167-1, CWA 14167-2, CWA 14170
[3] Recomendaciones RFC3739, ETSI TS 101 862, ETSI TS 101733.
[4] The Design of a Cryptographic Security Architecture. Peter Gutmann. Disponible
en http://www.cs.auckland.ac.nz/~pgut001/pubs/usenix99.pdf
[5] American National Standards Institute. American National Standard X9.17:
Financial Institution Key Management (Wholesale), 1985.
[6] ANF Certification Policy Statement. www.anf.es/AC/Documentos
Componentes
criptográficos
entidad final
de ANF AC
Ref.
DT_Creacion_componenetes_criptograficos_entidad_final.pdf
Versión:
1.1
OID: 1.3.6.1.4.1.18332.14.1
Página
27 de
27
Descargar