Так что для проекта 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();
}
}