Librería auxiliar para convertir templates ISO/IEC 19794-2:2005 y ANSI INCITS 378-2004 a la forma ISOCC clave para la verificación biométrica match on card de los chips basados en los estándares ISO7816-4, la construcción de los módulos están basado es en el estandar MINEX, propuesto por el NIST
Antes que nada considero muy importante, el detallar brevemente como funciona esta librería, ya que no he visto documentación alguna de los estándares biométricos en español
SEP7US Match on Card 0x7E3
Cualquier modificación que se realice sin la supervisón y/o consentimiento del corre por su cuenta y riesgo. Cualquier cambio en el código alterará drásticamente los resultados de la verificativa sobre cualquier aplicación PIV Smart Card
- C++
- Java Native Interface
Generación plantilla ISOCC con uso directo para Aplicaciones PIV en tarjetas inteligentes ISO/IEC 7816-4
La compatibilidad de esta herramienta se basa en los 2 siguientes tipos de template
- ISO/IEC 19794-2:2005
- ANSI INCITS 378-2004
- Conteo de Minucias
- Recuantización Espacial
- Recuantización Angular
- Sorting de Minucias
- Obtención directa de la plantilla ISOCC
- Adición de cabeceras ISO/IEC 7816-4
Es importante delimitar la posición de la data, dependiendo el template que se reciba
Posición donde comienza la data en plantillas ISO/IEC 19794-2:2005 > (DEC=18, HEX=12)
posDataTemplate = 0x12;
Posición donde comienza la data en plantillas ANSI INCITS 378-2004 > (DEC=20, HEX=14)
posDataTemplate = 0x14;
Para la mayoría de variables o definiciones nos guiaremos de la variable que indica donde comienzan la data de la minucia
posDataTemplate;
short numMinutiae = (short) fTemplate[posDataTemplate+9] & 0xFF;
Dada la forma del template (X, Y, T|A) el tamaño del array estará determinado por el número de minucias multiplicado por 3
// numMinutiae
short sizeISOCC = numMinutiae * 3;
Este proceso sirve para expresar las coordenadas de las minucias en términos de 0.1mm
CoordMM = 10 * Coord / RES
CoordUNITS = CoordMM / 0.1
CoordCC = 0.5 + CoordUNITS
Es importante primero obtener la resolución del template
short xres = (short) (fTemplate[posDataTemplate+0] << 8 | fTemplate[posDataTemplate+1]) & 0xFF;
short yres = (short) (fTemplate[posDataTemplate+2] << 8 | fTemplate[posDataTemplate+3]) & 0xFF;
La resolución se encuentra expresada en 2 bytes, por lo tanto se debe de trasladar a un dato de tipo short, para ello el primer byte se corre 8 bits <<8, luego con el segundo byte se hace una operación de compuerta lógica OR |, y por último se debe de hacer la operación AND & 0xFF
Para calcular la coordenada X en formato ISOCC y usando la expresión base, quedará de la siguiente manera
*pcoordmmX = 10.0 * (double) *ptmpx / xres;
*pcoordunitsX = *pcoordmmX / 0.1;
*pcoordccX = (short)(.5 + *pcoordunitsX);
Para calcular la coordenada Y en formato ISOCC y usando la expresión base, quedará de la siguiente manera
*pcoordmmY = 10.0 * (double) *ptmpy / yres;
*pcoordunitsY = *pcoordmmY / 0.1;
*pcoordccY = (short)(.5 + *pcoordunitsY);
La recuantización angular sirve para representar en 6 bits el ángulo de la minucia teniendo en cuenta que la resolución de los angluos varia en los 2 formatos ANSI e ISO, para representar en 6 bits un ángulo cuyo valor máximo será 360, se hará de la siguiente manera.
360/64 = 5.625
Entonces se puede delimitar como constante
float ISOCC_ANGLE_RESOLUTION = 5.625f;
Previo a la recuantización angular es necesario expresar el angulo en formato normal (360°), para ello cada tipo de template representa los angulos de manera distinta
El angulo se expresa en 8 bits 0xFF
360/256 = 1.40625
Por lo tanto se puede delimitar como constante de la siguiente forma
ANGLE_RESOLUTION = 1.40625f;
Resolución del ángulo para formato ANSI INCITS 378-2004 expresado en su forma normal dividido 2 (180°)
360/180 = 2
Por lo tanto se puede delimitar como constante de la siguiente forma
ANGLE_RESOLUTION = 2;
El tipo de minucia se guarda en la posición +10 de donde inicia los datos del template
posDataTemplate+10;
Solamente ocupa los 2 primeros bits de este, los 6 bits restantes corresponden a una coordenada X mayor a 0xFF siendo este un axuliar del siguiente byte, los 2 bits del tipo de minucia son claves para la representación del tercer tipo en la recuantización angular, por lo tanto debemos de extraerlos con la operación lógica AND 0xC0
& 0xC0
Donde C0 = 11000000 (Expresado en bits)
La operación lógica AND por cero, anula todos los bytes restantes despues del segundo bit, aunque en pruebas varias los 14 bits restantes nunca se utilizan, realizamos la operación para casos especiales, ya que el mismo estándar señala que los 14 bits restantes si corresponden al uso de la coordenada X, por lo tanto la operación quedará de la siguiente forma
*ptmpt = (short) fTemplate[j] & 0xC0;
Teniendo en cuenta todo lo anterior el cálculo final de la recuantización angular, queda asi
tmpCAngle = ANGLE_RESOLUTION * (*ptmpa);
tmpFAngle = tmpCAngle/ISOCC_ANGLE_RESOLUTION;
short t = (*ptmpt | tmpFAngle) & 0xFF;
Aunque algunas tarjetas smartcard no necesitan ningun tipo de sorting, se incluyen las 4 funciones principales
Cada minucia ya convertida a ISOCC con su forma (X, Y, T|A), es ordenada direcatamente con base a la posicón X de la misma, en orden ascendente (de menor a mayor)
void XYAsc(unsigned char *a, short n);
Cada minucia ya convertida a ISOCC con su forma (X, Y, T|A), es ordenada direcatamente con base a la posicón X de la misma, en orden descendente (de mayor a menor)
void XYDsc(unsigned char *a, short n);
Cada minucia ya convertida a ISOCC con su forma (X, Y, T|A), es ordenada direcatamente con base a la posicón Y de la misma, en orden ascendente (de menor a mayor)
void YXAsc(unsigned char *a, short n);
Cada minucia ya convertida a ISOCC con su forma (X, Y, T|A), es ordenada direcatamente con base a la posicón Y de la misma, en orden descendente (de mayor a menor)
void YXDsc(unsigned char *a, short n);
Obtiene el template convertido a ISO Compact Card
- templateFormat: Se debe especificar el formato del template 0xFF para formato ISO/IEC 19794-2:2005, y 0x7F para formato ANSI INCITS 378-2004
- fTemplate: EL puntero que apunta al array que contiene el template base
- sorting: Se debe especificar el sorting en el parámetro con alguno de los siguientes valores en formato byte
0x00 : Obtiene el sorting XY Ascendente (XYAsc)
0x0F : Obtiene el sorting XY Descendente (XYDsc)
0x10 : Obtiene el sorting YX Ascendente (YXAsc)
0x1F : Obtiene el sorting YX Descendente (YXDsc)
__declspec(dllexport) unsigned char *ISOCC(unsigned char templateFormat, unsigned char *fTemplate, unsigned char sorting);
Obtiene el template convertido a ISO Compact Card, añadiendo las cabeceras del comando de verificación principal PIV
PIV: Acrónimo de Personal Identification Verify está delimitado
APDUVerify[0]=CLA;
APDUVerify[1]=INS;
APDUVerify[2]=P1;
APDUVerify[3]=P2;
APDUVerify[4]=sizeISOCC+5;
APDUVerify[5]=0x7F;
APDUVerify[6]=0x2E;
APDUVerify[7]=sizeISOCC+2;
APDUVerify[8]=0x81;
APDUVerify[9]=sizeISOCC;
Generalmente el comando de aplicación usado es 0x00 0x21, se deja libre elección para casos especiales, en los bytes 5 y 6 se añade la cabecera
7F2E: Es indicativa de "Biometric data template", indicado en el estándar ISO/IEC 19794-2
- CLA: Class of instruction
- INS: Instruction code
- P1: Instruction parameter 1
- P2: Instruction parameter 2
- templateFormat: Se debe especificar el formato del template 0xFF para formato ISO/IEC 19794-2:2005, y 0x7F para formato ANSI INCITS 378-2004
- fTemplate: EL puntero que apunta al array que contiene el template base
- sorting: Se debe especificar el sorting en el parámetro con alguno de los siguientes valores en formato byte
0x00 : Obtiene el sorting XY Ascendente (XYAsc)
0x0F : Obtiene el sorting XY Descendente (XYDsc)
0x10 : Obtiene el sorting YX Ascendente (YXAsc)
0x1F : Obtiene el sorting YX Descendente (YXDsc)
__declspec(dllexport) unsigned char *Verify(unsigned char CLA, unsigned char INS, unsigned char P1, unsigned char P2, unsigned char templateFormat, unsigned char *fTemplate, unsigned char sorting);
MIT