2012-11-08 4 views
3

아이폰에서 PIV 스마트 카드와 인터페이스하려고합니다. 필요한 라이브러리가로드되어 명령을 보낼 수 있습니다. 데이터 가져 오기와 응답 명령을 조합하여 스마트 카드에서 모든 관련 인증서를 검색 할 수 있습니다. 우리는 이제 일부 데이터에 서명하지만 6A80을받는 일반 인증 명령을 보내려고합니다. 이 명령을 연결합니다. 체인의 첫 번째 부분은 리턴 코드 90 00으로 성공적으로 실행되지만 두 번째 명령은 6a80을 제공합니다.스마트 카드 - 일반 인증 명령 6A 80

우리 카드 설명을 말한다

  1. RSA PKCS의 SHA-256 서명 # 1 V 1.5
  2. RSA 2048 비트 키

우리는 SHA1 (256) 및 패딩을 가진 우리의 데이터를 해싱된다 pkcs v 1.5 패딩. 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

명령란에 차이를 만들어서는 안되며, '6A 80'명령 필드에 잘못된 데이터가 아니라 경고를 기대한다면 ... –

답변

2

PKCS # 1 패딩 된 해시 값 대신 명령 데이터 필드에 해시 값만 보냅니다. 카드는 서명 작업의 일부로 패딩을 수행합니다.

관련 문제