Функция шифрования и дешифрования JavaCard, вызываемая с pyscard

У меня есть апплет Java-карты, который реализует шифрование и дешифрование с использованием RSA PKCS#1 с ключом CRT (китайская теорема об остатках) 1024. Вот мой код ниже:

Конструктор:

    private CryptoApplet() {
        generateKeyPair();

        cipher = Cipher.getInstance(Cipher.ALG_RSA_PKCS1, false);

        outputByte = new byte[256];
        outputByte2 = new byte[117];
        outBuff = new byte[128];
        outBuff2 = new byte[117];
    }

Функция шифрования (Java-карта):

private void encrypt(APDU apdu) {
        byte[] buffer = apdu.getBuffer();
        short lc = apdu.getIncomingLength();
        short dataOffset = apdu.getOffsetCdata();

        short blocksize = 117;
        short inOffset = (short) 0;
        short outOffset = (short) 0;

        if (!pubKey.isInitialized() || pubKey == null) {
            ISOException.throwIt(STORAGE_KU_NOT_INITIALIZED);
        }
        cipher.init(pubKey, Cipher.MODE_ENCRYPT);

        short dataLeft = lc;
        while (dataLeft > 0) {
            if (dataLeft < blocksize)
                blocksize = dataLeft;

            outOffset = cipher.doFinal(buffer, (short) dataOffset, (short) blocksize, outBuff, (short) 0);
            Util.arrayCopy(outBuff,(short) 0,outputByte,inOffset,(short) outOffset);

            inOffset += outOffset;
            dataOffset += blocksize;
            dataLeft -= blocksize;
        }

        apdu.setOutgoingAndSend((short) 0, (short) outputByte.length);
    }

Функция расшифровки (Java-карта):

private void decrypt(APDU apdu) {
        byte[] buffer = apdu.getBuffer();
        short lc = apdu.getIncomingLength();
        short dataOffset = apdu.getOffsetCdata();

        short blocksize = 128;
        short inOffset = (short) 0;
        short outOffset = (short) 0;

        cipher.init((RSAPrivateCrtKey) keys.getPrivate(), Cipher.MODE_DECRYPT);

        short dataLeft = lc;
        while (dataLeft > 0) {
            if (dataLeft < blocksize)
                blocksize = dataLeft;

            outOffset = cipher.doFinal(buffer, (short) dataOffset, (short) blocksize, outBuff2, (short) 0);
            Util.arrayCopy(outBuff2,(short) 0,outputByte2,inOffset,(short) outOffset);

            inOffset += outOffset;
            dataOffset += blocksize;
            dataLeft -= blocksize;
        }

        apdu.setOutgoingAndSend((short) 0, (short) outputByte2.length);
    }

Функция расшифровки и шифрования вызывается из кода Python ниже (с использованием пакета pyscard), и она прекрасно работает для шифрования. Но каждый раз, когда я пытаюсь вызвать функцию расшифровки, она выдает ошибку(отклик sw1 = 6F и sw2 = 00).

Зашифровать абонента (python/pyscard) (функция 0x41):

#! /usr/bin/env python
from smartcard.System import readers
from smartcard.util import *
import struct

# define the APDUs used in this script
f_input = open('4x6.JPG','rb')
list_input = list(bytearray(f_input.read()))
f_input.close()

SELECT = [0x00, 0xA4, 0x04, 0x00, 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00]

# get all the available readers
r = readers()
print "Available readers:", r

reader = r[0]
print "Using:", reader

connection = reader.createConnection()
connection.connect()

data, sw1, sw2 = connection.transmit(SELECT)
print data
print "Select Applet: %02X %02X" % (sw1, sw2)


COMMAND = [0x80, 0x41, 0x00, 0x00, 0x00]
list_output = []

lengthCommandData = 234

amountSendAPDU = len(list_input)/lengthCommandData
left = len(list_input) % lengthCommandData
if (left > 0):
    amountSendAPDU += 1

for b in range(amountSendAPDU):
    DATA_COMMAND = list_input[b*lengthCommandData:(b+1)*lengthCommandData]
    lengthData = len(DATA_COMMAND)

    tmp = lengthData/117
    left = lengthData%117
    if (left > 0):
        tmp += 1
    lengthResp = tmp*128
    LE = [ord(c) for c in struct.pack("!H",lengthResp)]
    LE = [0x00] + LE

    LC = [ord(c) for c in struct.pack("!H",lengthData)]

    data, sw1, sw2 = connection.transmit(COMMAND + LC + DATA_COMMAND + LE)
    list_output = list_output + data

f_encrypted = open('4x6.enc','wb')
f_encrypted.write(bytearray(list_output))
f_encrypted.close()

Расшифровать вызывающего абонента (python/pyscard) (функция 0x42):

#! /usr/bin/env python
from smartcard.System import readers
from smartcard.util import *
import struct

# define the APDUs used in this script
f_input = open('4x6.enc','rb')
list_input = list(bytearray(f_input.read()))
f_input.close()

SELECT = [0x00, 0xA4, 0x04, 0x00, 0x0A, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00]

# get all the available readers
r = readers()
print "Available readers:", r

reader = r[0]
print "Using:", reader

connection = reader.createConnection()
connection.connect()

data, sw1, sw2 = connection.transmit(SELECT)
print data
print "Select Applet: %02X %02X" % (sw1, sw2)


COMMAND = [0x80, 0x42, 0x00, 0x00, 0x00]
list_output = []

lengthCommandData = 128

amountSendAPDU = len(list_input)/lengthCommandData
left = len(list_input) % lengthCommandData
if (left > 0):
    amountSendAPDU += 1

for b in range(amountSendAPDU):
    DATA_COMMAND = list_input[b*lengthCommandData:(b+1)*lengthCommandData]
    lengthData = len(DATA_COMMAND)

    tmp = lengthData/128
    left = lengthData%128
    if (left > 0):
        tmp += 1
    lengthResp = tmp*117
    LE = [ord(c) for c in struct.pack("!H",lengthResp)]
    LE = [0x00] + LE

    LC = [ord(c) for c in struct.pack("!H",lengthData)]

    data, sw1, sw2 = connection.transmit(COMMAND + LC + DATA_COMMAND + LE)
    list_output = list_output + data
    print "%02X %02X" % (sw1, sw2)

f_encrypted = open('output.JPG','wb')
f_encrypted.write(bytearray(list_output))
f_encrypted.close()

Вопрос:

  1. Когда я попытался найти проблему, я обнаружил, что проблема в cipher.doFinal () в функции расшифровки (Java-карта). Но я до сих пор не знаю причину ошибки в cipher.doFinal (). Может кто-нибудь помочь мне решить эту проблему расшифровки?
  2. Я пытался использовать расширенный апплет, но я не могу передать данные больше, чем 255 байт в python/pyscard. Кто-нибудь может мне помочь и подсказать, как передать данные с python / pyscard длиной более 255 байт?
  3. Каков максимальный размер данных, которые можно отправить через APDU? Насколько я знаю, расширенный APDU может получать 65535 байт данных, но когда я пытался отправить 59904 байт данных с python/pyscard, он выдает мне ошибку вроде:

ошибка 3:

Traceback (most recent call last):
          File "encrypt.py", line 58, in <module>
            data, sw1, sw2 = connection.transmit(COMMAND + LC + DATA_COMMAND + LE)
          File "C:\Users\X\Anaconda\lib\site-packages\smartcard\CardConnectionDecorat
        or.py", line 82, in transmit
            return self.component.transmit(bytes, protocol)
          File "C:\Users\X\Anaconda\lib\site-packages\smartcard\CardConnection.py", l
        ine 144, in transmit
            data, sw1, sw2 = self.doTransmit(bytes, protocol)
          File "C:\Users\X\Anaconda\lib\site-packages\smartcard\pcsc\PCSCCardConnecti
        on.py", line 205, in doTransmit
            SCardGetErrorMessage(hresult))
        smartcard.Exceptions.CardConnectionException: Failed to transmit with protocol T
        1. The data area passed to a system call is too small.

Спасибо и извините за длинный вопрос, новичок здесь.

0 ответов

Другие вопросы по тегам