Flutter中解密后显示pdf文件的问题

问题描述 投票:0回答:1

我正在开发一个 Flutter 应用程序,其中涉及从互联网获取 pdf 文件,加密并将其存储在应用程序文件目录中,然后检索、解密它以在应用程序中显示。 为此,我使用 https://pub.dev/packages/encryptSyncfusion pdf 查看器。 但是在解密和显示文件时我得到了

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);

我在日志中得到一个列表,其中包含未加密字节和解密字节的相同数据。 此外,当在加密器对象中使用默认填充时,我在解密字节方法中得到无效或损坏的填充。 问题出在哪里?

flutter encryption aes syncfusion
1个回答
0
投票

我们审查了提供的示例,并创建了一个类似的应用程序,该应用程序使用您通过 https://pub.dev/packages/encrypt 共享的包来加密和解密文件。我们已成功在 SfPdfViewer 中加载解密的字节,并且它在我们这边正确显示了 PDF 文档。我附上了示例的代码片段供您参考。请尝试此操作,如果您仍然遇到任何问题,请告诉我们。如果是,请分享重现该问题的修改后的代码示例。这将有助于我们尽快提供及时的解决方案。

代码片段:

import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:syncfusion_flutter_pdfviewer/pdfviewer.dart';
import 'package:encrypt/encrypt.dart' as encrypt;
import 'package:http/http.dart' as http;

void main() {
  runApp(MaterialApp(
    title: 'Syncfusion PDF Viewer Demo',
    home: HomePage(),
  ));
}

/// Represents Homepage for Navigation
class HomePage extends StatefulWidget {
  @override
  _HomePage createState() => _HomePage();
}

class _HomePage extends State<HomePage> {
  final GlobalKey<SfPdfViewerState> _pdfViewerKey = GlobalKey();
  Uint8List? _documentBytes;

  @override
  void initState() {
    super.initState();
    loadPdfDocument();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Syncfusion Flutter PDF Viewer'),
        ),
        body: _documentBytes != null
            ? SfPdfViewer.memory(_documentBytes!)
            : Container());
  }

  /// Handling the encryption, decryption and load the document in SfPDfViewer.
  Future<void> loadPdfDocument() async {
    const url =
        'https://cdn.syncfusion.com/content/PDFViewer/flutter-succinctly.pdf';
    final response = await http.get(Uri.parse(url));

    if (response.statusCode == 200) {
      final fileBytes = response.bodyBytes;
      final key = encrypt.Key.fromSecureRandom(32);
      final iv = encrypt.IV.fromSecureRandom(16);
      final encrypter =
          encrypt.Encrypter(encrypt.AES(key, mode: encrypt.AESMode.ctr));

      // Encrypt the file
      final encryptedBytes = encrypter.encryptBytes(
        fileBytes,
        iv: iv,
      );
      // Decrypt the file
      final decryptedBytes = encrypter.decryptBytes(encryptedBytes, iv: iv);
      // For loading the decrypted bytes in SfPdfViewer.
      _documentBytes = Uint8List.fromList(decryptedBytes);
      setState(() {});
    }
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.