Writing more then 65kb results in corrupted data
See original GitHub issueBugreport
Writing more then 65kb results in corrupted data
reading the corrupt data results in
Unexpected token [...] in JSON at position 65536
Data written
Data read
The Code
Writing 30k Integers into the buffer
More Context
The Error
The Version
"react-native-keychain": "^3.0.0-rc.3"
react-native-keychain@^3.0.0-rc.3:
version "3.0.0"
resolved "https://registry.yarnpkg.com/react-native-keychain/-/react-native-keychain-3.0.0.tgz#29da1dfa43c2581f76bf9420914fd38a1558cf18"
integrity sha512-0incABt1+aXsZvG34mDV57KKanSB+iMHmxvWv+N6lgpNLaSoqrCxazjbZdeqD4qJ7Z+Etp5CLf/4v1aI+sNLBw==
The Device
A real Android 6.0 Device using react-native debug mode(maybe this causes trouble?)
The Current Solution
Split up the data into buckets, have another key which indexes the buckets.
This reduces speed, since there are more read/write Operations.
Assume:
- Bucketsize b
- Datapoints n
Results in ceil(n/b) + 1
read/write operations
- Blue = IndexService
- Green = BucketServiceName
- Red = BucketService
- Grey = Result/Input
- Bucketsize = 1
Note: since its not easy to determine the size of an Object in byte, you have to select a size for the buckets which you consider save not to surpass 65kb.
The Current Solution’s Code
Sorry for that mess, cleanup is not yet done - ping me here for a followup 😉
static readKeychain = async () => {
console.log('readKeychain');
const keyindex = await Keychain.getGenericPassword(VotesLocal.KEYCHAIN_INDEX_SERVICE);
if (!keyindex) {
return null;
}
let indexchain = JSON.parse(keyindex.password);
console.log(`readKeychain: ${JSON.stringify(indexchain)}`);
indexchain.d = [];
await Promise.all(
indexchain.i.map(async serviceId => {
const service = VotesLocal.KEYCHAIN_VOTES_SERVICE + serviceId;
const setData = await Keychain.getGenericPassword(service);
console.log(`readKeychain: ${JSON.stringify(service)}`);
console.log(`readKeychain: ${JSON.stringify(setData)}`);
if (setData) {
indexchain.d.push(...JSON.parse(setData.password));
}
}),
);
delete indexchain.i;
console.log(`readKeychain: ${JSON.stringify(indexchain)}`);
return indexchain;
};
static writeKeychain = async data => {
console.log('writeKeychain');
console.log(`writeKeychain: ${JSON.stringify(data)}`);
let index = [];
// Split Data into packages to avoid error on 65k
while (data.d.length > 0) {
const set = data.d.splice(0, VotesLocal.KEYCHAIN_MAXSIZE);
const setServiceId = index.length;
const setService = VotesLocal.KEYCHAIN_VOTES_SERVICE + setServiceId;
console.log(`writeKeychain: ${JSON.stringify(setService)}`);
console.log(`writeKeychain: ${JSON.stringify(set)}`);
await Keychain.setGenericPassword(
VotesLocal.KEYCHAIN_VOTES_KEY,
JSON.stringify(set),
setService,
);
index.push(setServiceId);
}
delete data.d;
data.i = index;
console.log(`writeKeychain: ${JSON.stringify(data)}`);
// console.log(JSON.stringify(data));
/*const dummy = [];
for (var i = 0; i < 30000; i++) {
dummy.push(i);
}
data.dummy = dummy;
console.log(data);
console.log(JSON.stringify(data));*/
return await Keychain.setGenericPassword(
VotesLocal.KEYCHAIN_INDEX_KEY,
JSON.stringify(data),
VotesLocal.KEYCHAIN_INDEX_SERVICE,
);
};
Furthermore
Since the corruption in the data seem to be random bytes (changing values), I consider it likely that this is a bufferoverflow?!
And yes - this library is made to contain credentials not data - I know that we abuse its scope 😉
(Possibly) Related
https://github.com/oblador/react-native-keychain/issues/120 https://github.com/oblador/react-native-keychain/issues/174 https://github.com/oblador/react-native-keychain/issues/208
Issue Analytics
- State:
- Created 5 years ago
- Reactions:3
- Comments:6
Top GitHub Comments
I still have the same problem and also with the latest library versions the problem still exists.
Has somebody else an idea howto solve it instead splitting the reading and writing?
I guess it is also the same as https://github.com/oblador/react-native-keychain/issues/208 (?)
Just ran into this on Android 7.