我正在研究一个Flutter应用程序,它涉及从互联网上获取PDF文件,加密并将其存储在应用程序文件目录中,并检索,解密以在应用程序中显示。我正在使用https://pub.dev/packages/encrypt和Syncfusion pdf viewer来实现此目的。但是在解密和显示文件时,
ArgumentError{Invalid argument (position): Invalid Position:-1}
在SfPdfViewer中运行调试模式。代码为:
`SfPdfViewer.network(
widget.file!.link!,
key: _pdfViewerKey,
onDocumentLoaded: (PdfDocumentLoadedDetails details) async {
// final Directory tempPath = await getApplicationDocumentsDirectory();
// _tempFile = await File('${tempPath.path}/${widget.file!.title}.pdf')
// .writeAsBytes( await details.document.save());
}):FutureBuilder<Uint8List>(
future: getFileBytes(),
builder:(context,snapshot){
if(snapshot.hasData)
{
logger.i("Snapshot Data is ${snapshot.data}");
return SfPdfViewer.memory(snapshot.data!,key: _pdfViewerKey, );
}
else if(snapshot.hasData)
{
snapshot.printError();
return Text('Error');
}
else
{
return const Center(child: CircularProgressIndicator());
}
}
)
);
}
Future<Uint8List> getFileBytes() async
{
return await fileController.getDecryptedFile(name: widget.file!.title!);
}`
下载、加密和解密的方法有:
Future<void> downloadFile({required Files file})async
{
logger.e("Link of file to be downloaded is ${file.link}");
Response response=await download(url: file.link!);
final directory = await getApplicationDocumentsDirectory();
final filesDirectory = await Directory('${directory.path}/files').create(recursive: true);
String filePath='${filesDirectory.path}/${file.title!}.aes';
logger.i("Length of key is ${key.length}");
final encryptor=Encrypter(AES(key,padding: null));
logger.i("Unencrypted bytes: ${response.data}");
final encryptedBytes = encryptor.encryptBytes(response.data,iv: iv,);
final decryptedBytes = encryptor.decryptBytes(encryptedBytes,iv: iv,associatedData: encryptedBytes.bytes);
logger.i("encrypted bytes: ${encryptedBytes}");
final encryptedFile=File(filePath);
encryptedFile.writeAsBytesSync(encryptedBytes.bytes);
changeDownloadStatus(true);
}
Future<dynamic> download({required String url}) async
{
try{
String token=url.substring(url.indexOf("token")+7,url.indexOf("_gl"));
String alt=url.substring( url.indexOf("alt=")+5,url.indexOf("token="));
String gl=url.substring(url.indexOf("_gl=")+5);
Map<String,String> query={
"token":token,
"alt":alt,
"_gl":gl
};
Response response =await Dio().get(url.substring(0,url.indexOf("?")),options: Options(responseType: ResponseType.bytes,
followRedirects: false,contentType: "application/pdf"),queryParameters: query);
logger.i(response.data);
changeDownloadStatus(true);
return response;
}
on Exception catch(e)
{
logger.e(e.toString());
}
}
Future<Uint8List> getDecryptedFile({required String name}) async
{
final directory = await getApplicationDocumentsDirectory();
final filesDirectory = Directory('${directory.path}/files');
String filePath='${filesDirectory.path}/$name.aes';
File encryptedfile=File(filePath);
bool isPresent=await encryptedfile.exists();
logger.i("File at path $filePath is present $isPresent");
Uint8List encryptedBytes=encryptedfile.readAsBytesSync();
logger.i("encrypted bytes: ${encryptedBytes}");
// Decrypt the file
final encryptor=Encrypter(AES(key,padding: null));
final decryptedBytes=encryptor.decryptBytes(Encrypted(encryptedBytes),iv: iv,associatedData: encryptedBytes);
return Uint8List.fromList(decryptedBytes);
}
Key和Iv的计算公式如下:
final iv=IV.fromLength(16);
final key=Key.fromSecureRandom(32);
我得到一个列表中的日志与未加密的字节和解密的字节相同的数据。另外,当在decryptor对象中使用默认填充时,我会得到**解密方法中无效或损坏的填充。**问题在哪里?
1条答案
按热度按时间raogr8fs1#
我们已经查看了提供的示例,并创建了一个类似的应用程序,使用您通过https://pub.dev/packages/encrypt共享的包加密和解密文件。我们已经成功地在SfPdfViewer中加载了解密的字节,并且它在我们的终端上正确地显示了PDF文档。我附上了示例的代码片段供您参考。请尝试一下,让我们知道你是否仍然面临任何问题。如果你是,请分享修改后的代码示例,重现问题。这将有助于我们尽快提供及时的解决方案。
验证码: