Я неправильно сериализовал SealedObject? - PullRequest
0 голосов
/ 29 апреля 2020

Так что для проекта Android мне нужно писать и читать из NF C тега. Мой код NFCReader работает очень хорошо, когда я пытаюсь писать и читать текстовые записи. Однако, чтобы обезопасить систему, я пытаюсь запечатать мой TagProfile объект в SealedObject с помощью Cipher, а затем сериализовать этот SealedObject, чтобы записать его в тег NF C. Чтобы прочитать тег, я пытаюсь десериализовать SealedObject, а затем получить из него объект TagProfile.

Кажется, что код записи работает нормально. Однако, когда я пытаюсь прочитать тег, я получаю следующую ошибку: java.io.StreamCorruptedException: invalid stream header: 02656EAC

Мне интересно, пишу я или читаю данные неправильно. Я думаю, что это связано с сериализацией больше, чем с шифрованием. Я искал эту ошибку, но не могу найти пример с тем же заголовком, который выдается. Я нашел this , но я использую ByteArrayStreams и ObjectStreams для ввода и вывода. В любом случае, вот мои методы èncryptProfile() и decryptProfile(), которые также выполняют сериализацию. Первый вызывается при создании NdefRecord для записи, а второй - при создании TagProfile из полезной нагрузки NdefRecord.

    private byte[] encryptProfile(TagProfile tagProfile) throws InvalidKeyException, IOException, IllegalBlockSizeException {

        cipher.init(Cipher.ENCRYPT_MODE, key);
        SealedObject sealedProfile = new SealedObject(tagProfile, cipher);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);
        oos.writeObject(sealedProfile);
        oos.flush();
        return bos.toByteArray();
    }

...

    private TagProfile decryptProfile(byte[] bytes) throws IOException, ClassNotFoundException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream ois = new ObjectInputStream(bis);
        SealedObject sealedObject = (SealedObject) ois.readObject();
        cipher.init(Cipher.DECRYPT_MODE, key);
        return (TagProfile) sealedObject.getObject(cipher);
    }

Ошибка выдается, когда я выполняю экземпляр и инициализирую ObjectInputStream ois на decryptProfile(). Объекты Cipher и Key создаются глобально.

РЕДАКТИРОВАТЬ: я добавляю код, который я использую, чтобы записать NdefMessage в тег и построить из него TagProfile. Работал нормально, используя простые тексты (хотя и с немного другой реализацией).

// ---------- WRITE

    public void writeToTag(TagProfile profile, Tag tag) throws IOException, FormatException, IllegalBlockSizeException, InvalidKeyException, InvalidAlgorithmParameterException, NoSuchPaddingException, NoSuchAlgorithmException {

/*      Plain text implementation:

        NdefRecord[] records = {
                createRecord(profile.id),
                createRecord(profile.name),
                ...
        };
        NdefMessage message = new NdefMessage(records);
*/      
        NdefRecord[] encryptedRecord = {
                createRecord(profile)
        };
        NdefMessage encryptedMessage = new NdefMessage(encryptedRecord);

        Ndef ndef = Ndef.get(tag);
        ndef.connect();
        ndef.writeNdefMessage(encryptedMessage);
        ndef.close();
    }

    private NdefRecord createRecord(TagProfile tagProfile) throws IOException, NoSuchPaddingException, InvalidKeyException, NoSuchAlgorithmException, IllegalBlockSizeException, InvalidAlgorithmParameterException {

        byte[] profileBytes = encryptProfile(tagProfile);
        String lang       = "en";
        byte[] langBytes  = lang.getBytes("US-ASCII");
        int    langLength = langBytes.length;
        int    bytesLength = profileBytes.length;
        byte[] payload    = new byte[1 + langLength + bytesLength];

        payload[0] = (byte) langLength;

        System.arraycopy(langBytes, 0, payload, 1, langLength);
        System.arraycopy(profileBytes, 0, payload, 1 + langLength, bytesLength);

        NdefRecord recordNFC = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,  NdefRecord.RTD_TEXT,  new byte[0], payload);

        return recordNFC;
    }

// ---------- READ

    private TagProfile buildProfile(NdefMessage[] msgs) throws EmptyTagException, ImproperTagException{

        try {
            if (msgs == null || msgs.length == 0) throw new EmptyTagException();
            String[] records = new String[msgs[0].getRecords().length];

            if(records.length == tagLength) { // tagLength is the number of records I expect.
                return decryptProfile(msgs[0].getRecords()[0].getPayload());
            } else throw new ImproperTagException();

        } catch (Exception e) {
            e.printStackTrace();
            return new TagProfile();
        }
    }

...