Secure a SD-CARD and access it through app

Viewed 641

I have classified data in my SD-CARD. Is there any way to give access to the SD-CARD only through the app(react-native-project) ? File involved is .mp4 files.

Most of the solutions that i have found were about encrypting the data within the SD-CARD using AES-Encryption. But i am dealing with large files, therefore decrypting the entire file at once will throw memory out exception.

Secondly, Reading entire data stream-by-stream is a possibility, when i tested this method out the first set of stream(encrypted) will get successfully decrypted. The next stream will result in the error Malformed UTF-8 data.

Thirdly, I have tried dividing the file into pieces, decrypting each piece and appending each them to make a expected file. I am getting issues as specified here Issue Description.

EDIT:

Package Used for encryption: simple-crypto-js,

Function to decrypt file stream-by-stream:

 decryptfile() {
RNFetchBlob.fs
  .readStream(
    RNFetchBlob.fs.dirs.DCIMDir + "/encrypted.dat",
    "base64",
    4194303,
    30000      // 30 seconds buffer time before next stream comes
  )
  .then(stream => {
    let data = "";
    stream.open();
    stream.onData(chunk => {
      data += chunk;
      var decipherText = simpleCrypto.decrypt(chunk.toString());// First set of chunk will get successfully decrypted, the next chunk will result to Malformed UTF-8 data error
      this.writeOriginal(decipherText);
    });
    stream.onEnd(() => {
      console.log(data);
    });
  });
 }

Function to append data:

writeOriginal(decipherText) {
RNFetchBlob.fs
  .appendFile(
    RNFetchBlob.fs.dirs.DCIMDir + "/encrypt.mp4",
    decipherText,
    "base64"
  )
  .then(() => {

    console.log("File Written");
  })
  .catch(error => {
    console.log("file writing error", error);
  });
}

This is a Offline learning application where videos are stored in an SD Card and accessed in app.

1 Answers

Packages used are rn-fetch-blob & simple-crypto-js

Stream-by-Stream Encryption and writing in memory:

RNFetchBlob.fs
        .readStream(res.uri, "base64", 4194304, 4000)
        .then(stream => {
          let data = "";
          stream.open();
          stream.onData(chunk => {
            data += chunk;
            var cipherText = simpleCrypto.encrypt(chunk);
            RNFetchBlob.fs
              .appendFile(
                RNFetchBlob.fs.dirs.DCIMDir + "/encryptfile1.dat",
                cipherText,
                "base64"
              )
              .then(data => {
                console.log("file written", data); // gives buffer size use it for reading while decrypting
              })
              .catch(error => {
                console.log("file writing error", error);
              });
          });
          stream.onEnd(() => {
            console.log(data.length);
          });
        });

Stream-by-Stream Decryption:

RNFetchBlob.fs
  .readStream(
    RNFetchBlob.fs.dirs.DCIMDir + "/encryptfile1.dat",
    "base64",
    5592464,
    4000
  )
  .then(stream => {
    let data = "";
    stream.open();
    stream.onData(chunk => {
      data += chunk;
      var decipherText = simpleCrypto.decrypt(chunk.toString());
      this.writeOriginal(decipherText);
    });
    stream.onEnd(() => {
      this.setState({ playvideo: !this.state.playvideo });
      console.log("file decrypted");
    });
  });

Function to append decrypted base64 and generate .mp4 file:

writeOriginal(decipherText) {
RNFetchBlob.fs
  .appendFile(
    RNFetchBlob.fs.dirs.DCIMDir + "/encryptfile2.mp4",
    decipherText,
    "base64"
  )
  .then(() => {
    console.log("File Written");
  })
  .catch(error => {
    console.log("file writing error", error);
  });
}
Related