2012-11-08 40 views
3

我們試圖在iphone上與PIV智能卡進行接口。我們已經加載了必要的庫並可以發送命令。通過使用獲取數據和獲取響應命令的組合,我們可以從智能卡中檢索所有相關的證書。我們現在正嘗試發送一般認證命令來簽署一些數據,但接收6A80。我們正在鏈接這個命令。鏈的第一部分成功執行,返回代碼爲90 00,但第二個命令給出了6a80。智能卡 - 通用身份驗證命令6A 80

我們的網卡描述說

  1. RSA PKCS#1體積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]; 
} 

} 
+1

乍一看我沒有看到任何明顯的錯誤。也許你可以嘗試發送散列值? –

+0

謝謝貓頭鷹的答案。我們只是散列值和除一個之外的所有卡片,都能正確響應。對於使用6A 80響應的卡,使用的協議是T = 0(所有其他卡使用T = 1)。協議是否有所作爲? –

+0

它應該沒有什麼區別Himanshu,如果它你會期望一個警告,而不是'6A 80'「命令字段中的無效數據」... –

回答

2

只發送指令數據字段,而不是PKCS#1填充的哈希值的哈希值。該卡可能會作爲簽名操作的一部分進行填充。