3
아이폰에서 PIV 스마트 카드와 인터페이스하려고합니다. 필요한 라이브러리가로드되어 명령을 보낼 수 있습니다. 데이터 가져 오기와 응답 명령을 조합하여 스마트 카드에서 모든 관련 인증서를 검색 할 수 있습니다. 우리는 이제 일부 데이터에 서명하지만 6A80을받는 일반 인증 명령을 보내려고합니다. 이 명령을 연결합니다. 체인의 첫 번째 부분은 리턴 코드 90 00으로 성공적으로 실행되지만 두 번째 명령은 6a80을 제공합니다.스마트 카드 - 일반 인증 명령 6A 80
우리 카드 설명을 말한다
- RSA PKCS의 SHA-256 서명 # 1 V 1.5
- 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];
}
}
첫눈에 눈부신 오류가 보이지 않습니다. 어쩌면 당신은 단지 해시 값을 보내고 시도 할 수 있을까요? –
답변을 주셔서 감사합니다. 해시 값과 카드를 제외한 모든 카드가 올바르게 응답합니다. 6A 80으로 응답 한 카드의 경우 사용 된 프로토콜은 T = 0입니다 (다른 모든 카드는 T = 1을 사용함). 프로토콜이 다른 점이 있습니까? –
명령란에 차이를 만들어서는 안되며, '6A 80'명령 필드에 잘못된 데이터가 아니라 경고를 기대한다면 ... –