encryptFile method
Encrypt a file content The function takes all the content in a file and encrypt them using the key and store the ciphertext in the same file
Implementation
Future<void> encryptFile(String filePath, String fileName) async {
/// Encryption file URL
String encFileUrl =
webId.replaceAll('profile/card#me', filePath + '/' + fileName);
/// Get plaintext file content
String fileContent = await fetchFile(filePath + '/' + fileName);
/// Get encryption key that is stored in the local storage
String encKey = appStorage.getItem('encKey');
/// Encrypt the plaintext file content
List encryptValRes = encryptVal(encKey, fileContent);
String encryptValStr = encryptValRes[0];
String ivValStr = encryptValRes[1];
/// Delete the existing file with plaintext and create a new file with ciphertext
String delResponse = await deleteItem(false, filePath + '/' + fileName);
if (delResponse == 'ok') {
String dPopToken =
genDpopToken(encFileUrl, rsaKeyPair, publicKeyJwk, 'PATCH');
String insertQuery =
genSparqlQuery('INSERT', '', encValPred, encryptValStr);
String insertResponse =
await runQuery(encFileUrl, dPopToken, insertQuery);
String dPopTokenIv =
genDpopToken(encFileUrl, rsaKeyPair, publicKeyJwk, 'PATCH');
String insertQueryIv = genSparqlQuery('INSERT', '', ivValPred, ivValStr);
String insertResponseIv =
await runQuery(encFileUrl, dPopTokenIv, insertQueryIv);
if (insertResponse == 'ok' && insertResponseIv == 'ok') {
/// Get the list of locations of files that are encrypted
var keyInfo = await fetchFile(encKeyFileLoc);
EncProfile keyFile = EncProfile(keyInfo.toString());
String encFileHash = keyFile.getEncFileHash();
String encIvVal = keyFile.getEncIvVal();
String fileListStr = '';
/// New list of locations
if (encFileHash.isEmpty) {
List fileList = ['$filePath/$fileName'];
fileListStr = jsonEncode(fileList);
} else {
String encFilePlaintext = decryptVal(encKey, encFileHash, encIvVal);
List fileList = jsonDecode(encFilePlaintext);
fileList.add('$filePath/$fileName');
fileListStr = jsonEncode(fileList);
}
/// Update the list of encrypted file locations in the server
if (fileListStr.isNotEmpty) {
String encKeyFileUrl =
webId.replaceAll('profile/card#me', encKeyFileLoc);
List fileListEncRes = encryptVal(encKey, fileListStr);
String fileListStrEnc = fileListEncRes[0];
String fileListIv = fileListEncRes[1];
// Update encrypted value
String dPopToken =
genDpopToken(encKeyFileUrl, rsaKeyPair, publicKeyJwk, 'PATCH');
String updateQuery = genSparqlQuery(
'UPDATE', '', encFilePred, fileListStrEnc,
prevObject: encFileHash);
String updateResponse =
await runQuery(encKeyFileUrl, dPopToken, updateQuery);
// Update iv value
String dPopTokenIv =
genDpopToken(encKeyFileUrl, rsaKeyPair, publicKeyJwk, 'PATCH');
String updateQueryIv = genSparqlQuery(
'UPDATE', '', ivValPred, fileListIv,
prevObject: encIvVal);
String updateResponseIv =
await runQuery(encKeyFileUrl, dPopTokenIv, updateQueryIv);
if (updateResponse != 'ok' || updateResponseIv != 'ok') {
throw Exception('Failed to update encrypted file locations.');
}
}
} else {
throw Exception('Failed to encrypt the file.');
}
} else {
throw Exception('Failed to delete the file! Try again in a while.');
}
}