智能卡 - 一般认证命令6A 80

时间:2012-11-08 15:45:50

标签: ios cryptography smartcard

我们尝试在iphone上与PIV智能卡连接。我们已经加载了必要的库并可以发送命令。使用get data和get response命令的组合,我们可以从智能卡中检索所有相关证书。我们现在尝试发送一般身份验证命令来签署一些数据,但接收6A80。我们正在联系这个命令。链的第一部分成功执行,返回码为90 00,但第二个命令给出6a80。

我们的卡片说明

  1. 带有SHA-256签名的RSA PKCS#1 v 1.5
  2. RSA 2048位密钥
  3. 我们使用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 :(得分:2)

仅在命令数据字段中发送哈希值,而不是PKCS#1填充哈希值。该卡可能会作为签名操作的一部分进行填充。