Смарт-карта - общая команда аутентификации 6A 80

Мы пытаемся взаимодействовать со смарт-картой PIV на iphone. У нас есть необходимые библиотеки и мы можем отправлять команды. Используя комбинацию команд получения данных и получения ответа, мы можем получить все соответствующие сертификаты со смарт-карты. Сейчас мы пытаемся отправить общую команду аутентификации для подписи некоторых данных, но получаем 6A80. Мы связываем эту команду. Первая часть цепочки успешно выполняется с кодом возврата 90 00, но вторая команда дает 6a80.

В описании карты сказано

  1. RSA PKCS # 1 v 1.5 с подписями SHA-256
  2. RSA 2048-битные ключи

Мы хэшируем наши данные с помощью SHA1 256 и заполняем их заполнением pkcs v 1.5. Мы также закодировали хеш с помощью кодировки DER. Но в любом случае (с кодировкой der или без) мы получаем ошибку 6a80. Вот наш код,

// gets data signed from the smart card
-(void) signData:(unsigned char *)origdata:(int) origdatalen:(int) key_reference :(int)        key_size:(int) hash_reference
{
    bool debug=false;
    unsigned char * encodedandpadded;
unsigned char * digest;
NSMutableString* cplc = [[NSMutableString alloc]init];
int derHeaderLen=0;
int keyModulo=0;
int digestLen=0;
if (key_size==2048){
    keyModulo=256;
} else if (key_size==1024){
    keyModulo=128;
}
unsigned char * derHeader=nil;

switch (hash_reference){

    case SHA1:
        derHeaderLen=15;
        derHeader=(unsigned char *) calloc(derHeaderLen,sizeof(unsigned char));
        derHeader[0]=0x30;
        derHeader[1]=0x21;
        derHeader[2]=0x30;
        derHeader[3]=0x09;
        derHeader[4]=0x06;
        derHeader[5]=0x05;
        derHeader[6]=0x2b;
        derHeader[7]=0x0e;
        derHeader[8]=0x03;
        derHeader[9]=0x02;
        derHeader[10]=0x1a;
        derHeader[11]=0x05;
        derHeader[12]=0x00;
        derHeader[13]=0x04;
        derHeader[14]=0x14;
        digestLen=CC_SHA1_DIGEST_LENGTH;
        digest = (unsigned char*) calloc(digestLen,sizeof(unsigned char));
        CC_SHA1(origdata, origdatalen,digest);

        break;
    case SHA256:
        derHeaderLen=19;
        derHeader=(unsigned char *) calloc(derHeaderLen,sizeof(unsigned char));
        derHeader[0]=0x30;
        derHeader[1]=0x31;
        derHeader[2]=0x30;
        derHeader[3]=0x09;
        derHeader[4]=0x06;
        derHeader[5]=0x09;
        derHeader[6]=0x60;
        derHeader[7]=0x86;
        derHeader[8]=0x48;
        derHeader[9]=0x01;
        derHeader[10]=0x65;
        derHeader[11]=0x03;
        derHeader[12]=0x04;
        derHeader[13]=0x02;
        derHeader[14]=0x01;
        derHeader[15]=0x05;
        derHeader[16]=0x00;
        derHeader[17]=0x04;
        derHeader[18]=0x20;
        digestLen=CC_SHA256_DIGEST_LENGTH;
        digest = (unsigned char*) calloc(digestLen,sizeof(unsigned char));
        CC_SHA256(origdata, origdatalen,digest);

        break;
    case SHA512:
        derHeaderLen=19;
        derHeader=(unsigned char *) calloc(derHeaderLen,sizeof(unsigned char));
        derHeader[0]=0x30;
        derHeader[1]=0x51;
        derHeader[2]=0x30;
        derHeader[3]=0x09;
        derHeader[4]=0x06;
        derHeader[5]=0x09;
        derHeader[6]=0x60;
        derHeader[7]=0x86;
        derHeader[8]=0x48;
        derHeader[9]=0x01;
        derHeader[10]=0x65;
        derHeader[11]=0x03;
        derHeader[12]=0x04;
        derHeader[13]=0x02;
        derHeader[14]=0x03;
        derHeader[15]=0x05;
        derHeader[16]=0x00;
        derHeader[17]=0x04;
        derHeader[18]=0x40;

        break;
    default:

        break;

}

   // {0x00, 0x01, PS, 0x00, T},
   bool derEncoding=true;
int psLen;
int finalLen;
if (derEncoding){
    psLen=keyModulo-3-(derHeaderLen+digestLen);
    finalLen=3+psLen+derHeaderLen+digestLen;

} else {
   psLen=keyModulo-3-(digestLen);
   finalLen=3+psLen+digestLen;
}
    encodedandpadded =(unsigned char *) calloc(finalLen,sizeof(unsigned char));
    int count=0;
    encodedandpadded[count++]=0x00;
    encodedandpadded[count++]=0x01;
   for (int i=0;i<psLen;i++){
       encodedandpadded[count++]=0xFF;
   }
   encodedandpadded[count++]=0x00;
   if (derEncoding) {
    for (int i=0;i<derHeaderLen;i++){
        encodedandpadded[count++]=derHeader[i];
    }
}

for (int i=0;i<digestLen;i++){
    encodedandpadded[count++]=digest[i];
}

if (debug){
     [cplc appendString:[NSString stringWithFormat:@" psLen=%d derHeaderLen=%d digestlent=%d finalLen=%d count=%d",psLen,derHeaderLen,digestLen,finalLen,count]];
    for (int i=0;i<finalLen;i++){
         [cplc appendString:[NSString stringWithFormat:@" %02x ",encodedandpadded[i]]];
    }
    [self printData:cplc];
}


[self generalAuthenticate:encodedandpadded :256];


}   


- (void) generalAuthenticate:(unsigned char *) paddeddata:(int) paddeddatalen{

bool debug=true;



PBSmartcardStatus result;

// the first command in the chain , we will send first 128 bytes in this command
unsigned char dat[] = {0x10, 0x87, 0x07, 0x9C};
NSMutableData * prepCommand1 = [[NSMutableData alloc] initWithBytes:dat length:4];
unsigned char dat2[] = {0x86,0x7C,0x84};
[prepCommand1 appendBytes:dat2 length:3];
unsigned char dat3[] = {0x82,0x00,0x81,0x80};
[prepCommand1 appendBytes:dat3 length:4];

unsigned char * part1 =(unsigned char *) calloc((paddeddatalen/2),sizeof(unsigned char));
unsigned char * part2=(unsigned char *) calloc((paddeddatalen/2),sizeof(unsigned char));
int count=0;
for(int i=0;i<(paddeddatalen/2);i++){
    part1[i]=paddeddata[count++];
}

[prepCommand1 appendBytes:part1 length:(paddeddatalen/2)];
for(int i=0;i<(paddeddatalen/2);i++){
    part2[i]=paddeddata[count++];
}
//the second command in the chain, we will send rest of 128 bytes in this command
unsigned char dat4[]={0x00, 0x87, 0x07, 0x9C, 0x80};
NSMutableData * prepCommand2 = [[NSMutableData alloc] initWithBytes:dat4 length:5];

[prepCommand2 appendBytes:part2 length:(paddeddatalen/2)];

unsigned char dat5[]={0x00};
[prepCommand2 appendBytes:dat5 length:1];



//unsigned char get_cplc_command[] = {0x10, 0x87, 0x07, 0x9C,(macOut.length+4),0x82,0x00,0x81,macOut.length};

NSMutableString* cplc = [[NSMutableString alloc]init];

unsigned char received_data[255] = {0};
unsigned short received_data_length;


// on input received_data_length holds the size of the receive buffer.
received_data_length = sizeof(received_data);
unsigned char * prepCmd1=(unsigned char *)[prepCommand1 bytes];
int prepCmd1Len=[prepCommand1 length];
// send the command APDU and get the response from the card.
if (debug){
    [cplc appendString:[NSString stringWithFormat:@"Length %d %d",prepCmd1Len,(paddeddatalen/2), count]];
    [self printData:cplc];
    for (int i=0;i<prepCmd1Len;i++){
            [cplc appendString:[NSString stringWithFormat:@"%02x",prepCmd1[i]]];
    }
    [self printData:cplc];

}
result = [smartcard transmit:prepCmd1
           withCommandLength:prepCmd1Len

           andResponseBuffer:received_data
           andResponseLength:&received_data_length];

LOG(@"transmit = %d", result);


// check if the command was succefully sent to the card
//    if(result != PBSmartcardStatusSuccess)
//    {
//        goto done;
//    }
if (debug){
[cplc appendString:[NSString stringWithFormat:@"Response bytes from card for general authenticate command %02X %02X length %d\n",received_data[received_data_length-2],received_data[received_data_length-1],received_data_length]];
[self printData:cplc];
}

unsigned char received_data_2[300] = {0};
unsigned short received_data_length_2;


// on input received_data_length holds the size of the receive buffer.
received_data_length_2 = sizeof(received_data_2);
unsigned char * prepCmd2=(unsigned char *)[prepCommand2 bytes];
int prepCmd2Len=[prepCommand2 length];
// send the command APDU and get the response from the card.
if (debug){
    [cplc appendString:[NSString stringWithFormat:@"Length %d",prepCmd2Len]];
    [self printData:cplc];
    for (int i=0;i<prepCmd2Len;i++){
        [cplc appendString:[NSString stringWithFormat:@"%02x",prepCmd2[i]]];
    }
    [self printData:cplc];

}
result = [smartcard transmit:prepCmd2
           withCommandLength:prepCmd2Len

           andResponseBuffer:received_data_2
           andResponseLength:&received_data_length_2];

if (debug){
    [cplc appendString:[NSString stringWithFormat:@"Response bytes from card for general authenticate command %02X %02X length %d\n",received_data_2[received_data_length_2-2],received_data_2[received_data_length_2-1],received_data_length_2]];
    [self printData:cplc];
}

}

person Himanshu Page    schedule 08.11.2012    source источник
comment
Я не вижу на первый взгляд явных ошибок. Может быть, вы могли бы попробовать отправить только хеш-значение?   -  person Maarten Bodewes    schedule 11.11.2012
comment
Спасибо olstead за ответ. Мы просто хэшируем, и все мои карты, кроме одной, реагируют правильно. Для карты, которая ответила 6A 80, используется протокол T = 0 (все остальные карты используют T = 1). Имеет ли значение протокол?   -  person Himanshu Page    schedule 13.11.2012
comment
Это не должно иметь значения, Химаншу, и если это произойдет, вы ожидаете предупреждения, а не 6A 80 недопустимые данные в поле команды ...   -  person Maarten Bodewes    schedule 14.11.2012


Ответы (1)


Отправляйте только хеш-значение в поле данных команды вместо хеш-значения, дополненного PKCS # 1. Карта, скорее всего, сделает заполнение как часть операции подписи.

person Maarten Bodewes    schedule 13.11.2012