Как отправить байты длиннее 256 через ответный apdu - PullRequest
0 голосов
/ 27 мая 2018

Посмотрите на приведенный ниже код:

private void send_certificate (APDU apdu) {


if(!pin.isValidated())ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
else{


    apdu.setOutgoing();
    apdu.setOutgoingLength((short)certificate.length);
    apdu.sendBytesLong(certificate,(short)0,(short)certificate.length);
}

}

Сертификат - это байтовый массив внутри апплета javacard, длина которого превышает 256. Как я могу отправить это, не получив APDUException.BAD_LENGTH?

Кроме того, при отправке этого байтового массива, как я могу получить этот байтовый массив из хост-приложения?Я пытаюсь выполнить следующее из хост-приложения:

CommandAPDU card_cert;
        ResponseAPDU resp4;
        card_cert =  new CommandAPDU(IDENTITY_CARD_CLA, SEND_CERTIFICATE, 0x00, 0x00);
        resp4 = c.transmit(card_cert);
        if(resp4.getSW()==0x9000) {
            byte [] response = resp4.getData();
            String certf= DatatypeConverter.printHexBinary(response);
            System.out.println("CERTIFICATE:" + certf + "--"+response.length);
            System.out.println(" signature to be verivied: " + DatatypeConverter.printHexBinary(card_signature));
            CertificateFactory certFac = CertificateFactory.getInstance("X.509");
            InputStream is = new ByteArrayInputStream(response);
            X509Certificate cert = ( X509Certificate ) certFac .generateCertificate( is ) ;
            Signature signature = Signature.getInstance("SHA1withRSA");
            signature.initVerify(cert.getPublicKey());

        signature.update(card_signature);
        if(card_signature !=null) {
            boolean ok =signature.verify(card_signature);
            if(ok==true)System.out.println("verification completed" ); 
    }
        }

, конечно, после if(resp4.getSW()==0x9000) ничего не выполняется, поскольку сертификат не был успешно отправлен в хост-приложение.Как этого достичь?

После того, как мой класс апплета реализовал ExtendedLength, я сделал следующее в моем методе send_certificate ():

    private void send_certificate (APDU apdu) {
    if(!pin.isValidated())ISOException.throwIt(SW_PIN_VERIFICATION_REQUIRED);
    else{ byte[] buffer = apdu.getBuffer();
          short LE = apdu.setOutgoing();
           short toSend = (short)certificate.length;
           short cert_offset =0;
           short len =240;           
           if (LE != toSend) {
              apdu.setOutgoingLength(toSend);
           } 
           while (toSend > 0) {                
               Util.arrayCopyNonAtomic(certificate, cert_offset, apdu.getBuffer(), (short)0, len);
                       apdu.sendBytes((short) 0, len);
                       toSend -= len;
                       cert_offset += len;
          }
    }   
}

Это не работает: Сбой с кодом ответа 28416.

1 Ответ

0 голосов
/ 28 мая 2018

Вы должны убедиться, что ваша реализация Java Card и читатель поддерживают расширенную длину.Может быть, что реализации имеют барьеры, которые будут запрещать использование полноразмерной расширенной длины: реализации могут (неправильно) ограничивать размер APDU, например.

Читатель может потребовать, чтобы ATR указывалувеличенная длинаЧипы NFC печально известны тем, что не реализовали расширенную длину правильно (а Android печально известен тем, что не включили эту функциональность, если они это делают).Вероятно, это не ваша проблема, поскольку слово состояния, похоже, генерируется картой.

В коде Java Card есть ошибка, она всегда должна использовать setOutgoingLength().Кажется, ваш код уже вызывает исключение при вызове этого метода, поэтому я ожидаю, что размер, который вы пытаетесь отправить, не поддерживается платформой.Кроме того, ваш исходный код, использующий sendBytesLong, также выглядит правильно.Конечно, ваш апплет должен реализовывать интерфейс тегов ExtendedLength.

Обратите внимание, что 6F00 (ваш код состояния, всегда используйте шестнадцатеричные числа, а не десятичные дроби) может генерироваться любым необработанным исключением времени выполнения , созданным на карте.Поэтому убедитесь, что ваша проблема не создается в другом месте, когда вы пытаетесь ее исправить.

К сожалению, расширенная длина - минное поле.Сейчас 2018 год, и мир смарт-карт все еще не может отправлять 32 / 64Ki -1 байт или более.Думаю, пришло время заменить ISO / IEC 7816-4 чем-то, что имеет смысл.

...