需要幫助加密/解密此格式的文件=>openssl aes-256-cbc-d -salt -pbkdf 2 -iter 10000-in encryptedfilename -out明文文件名

我有一個網站來加密和解密文件,我想創建一個flutter應用程序來用相同的格式加密和解密,但我不知道如何做到,下面是加密的格式

openssl aes-256-cbc -d -salt -pbkdf2 -iter 10000 -in encryptedfilename -out plaintextfilename

關于如何使用上面的格式創建加密/解密函數,有什么建議嗎?我已經嘗試了大部分flutter加密包,但沒有找到任何解決方案

   static Future<File?> aesEncryptTest(String password, File file) async {
    final _password = Password.hash(password, PBKDF2());
    var bytes = utf8.encode(_password);
    var digest = sha256.convert(bytes);
    var fDigest = md5.convert(digest.bytes);

    final key = Key.fromUtf8(fDigest.toString());
    final iv = IV.fromLength(16);

    final encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: "PKCS7"));

    final fileBytes = await file.readAsBytes();
    final encryptedData = encrypter.encryptBytes(fileBytes, iv: iv);

    File _file =
        await File(file.path + '.enc').writeAsBytes(encryptedData.bytes);

    _file.writeAsBytesSync(encryptedData.bytes);

    await FileServices.saveFile(_file.path);

    
    return encryptedFile;
  }

  static Future<File?> aesDecryptTest(String password, File file) async {
    final _password = Password.hash(password, PBKDF2());
    var bytes = utf8.encode(_password);
    var digest = sha256.convert(bytes);
    var fDigest = md5.convert(digest.bytes);

    final key = Key.fromUtf8(fDigest.toString());
    final iv = IV.fromLength(16);

    final encrypter = Encrypter(AES(key, mode: AESMode.cbc, padding: "PKCS7"));

    final fileBytes = await file.readAsBytes();
    final decryptedBytes = encrypter.decryptBytes(Encrypted(fileBytes), iv: iv);

    File _file =
        await File(withoutExtension(file.path)).writeAsBytes(decryptedBytes);

    _file.writeAsBytesSync(decryptedBytes);

    await FileServices.saveFile(_file.path, extraName: 'DECRYPTED');

    return File(decryptedFile);
  }
? 最佳回答:

對于加密,在Dart代碼中:

  • 必須生成隨機的8字節salt,
  • 32字節密鑰和16字節IV必須使用PBKDF2從密碼和salt導出,
  • 明文必須使用派生密鑰和IV使用AES-256、CBC模式和PKCS#7填充來加密,
  • 數據必須以OpenSSL格式格式化:Salted__的ASCII編碼加上8字節的salt加上密文。

一種可能的實施方式是:

import 'dart:math';
import 'dart:typed_data';
import 'dart:convert';
import 'package:pointycastle/export.dart';
import 'dart:io';

...

// generate random 8 bytes salt
SecureRandom secureRandom = getSecureRandom();
Uint8List salt = secureRandom.nextBytes(8);

// derive key and IV via password and salt
Uint8List passphrase = Uint8List.fromList(utf8.encode('my passphrase'));
Uint8List keyIv = deriveKeyIv(salt, passphrase);
Uint8List key = keyIv.sublist(0, 32);
Uint8List iv = keyIv.sublist(32);

// encrypt using AES-256, CBC mode
File ptFile = File('<path to plaintext.txt file>');
Uint8List ptFileBytes = await ptFile.readAsBytes();
Uint8List ciphertext = encryptAesCbcPkcs7(ptFileBytes, key, iv);

// apply OpenSSL format: Salted__ | <8 bytes salt> | ciphertext
Uint8List prefixSaltCiphertext = concatAndEncode(salt, ciphertext);

File ctFile = File('<path to ciphertext.enc file>');
await ctFile.writeAsBytes(prefixSaltCiphertext);

with

SecureRandom getSecureRandom() {
  List<int> seed = List<int>.generate(32, (_) => Random.secure().nextInt(256));
  return FortunaRandom()..seed(KeyParameter(Uint8List.fromList(seed)));
}

Uint8List deriveKeyIv(Uint8List salt, Uint8List passphrase){
  PBKDF2KeyDerivator derivator = PBKDF2KeyDerivator(HMac(SHA256Digest(), 64))
    ..init(Pbkdf2Parameters(salt, 10000, 32 + 16));
  return derivator.process(passphrase);
}

Uint8List encryptAesCbcPkcs7(Uint8List plaintext, Uint8List key, Uint8List iv){
  PaddedBlockCipherImpl paddingCipher = PaddedBlockCipherImpl(PKCS7Padding(), CBCBlockCipher(AESEngine()))
    ..init(true, PaddedBlockCipherParameters(ParametersWithIV(KeyParameter(key), iv), null));
  return paddingCipher.process(plaintext);
}

Uint8List concatAndEncode(Uint8List salt, Uint8List ciphertext){
  BytesBuilder prefixSaltCiphertext = BytesBuilder()
    ..add(utf8.encode('Salted__'))
    ..add(salt)
    ..add(ciphertext);
  return prefixSaltCiphertext.toBytes();
}

以這種方式生成的密文可以使用發布的OpenSSL聲明進行解密(順便說一句,該聲明用于解密而非加密)。

這里必須考慮到,OpenSSL在早期版本中使用MD5作為默認摘要,在v1.0中使用SHA256。上面的代碼采用SHA256。如果您有較舊的OpenSSL版本,則可以在OpenSSL語句中設置-md sha256?;蛘?,該代碼必須適應MD5。


對于解密,在Dart代碼中:

  • 必須從以OpenSSL格式編碼的加密數據中提取8字節salt和密文,
  • 32字節密鑰和16字節IV必須使用PBKDF2從密碼和salt導出,
  • 密文必須用這個密鑰和IV使用AES-256、CBC模式和PKCS#7填充來解密。

該實現類似于加密:

// extract salt and ciphertext
File ctFile = File('<path to ciphertext.enc file>');
Uint8List ctFileBytes = await ctFile.readAsBytes();
Uint8List salt = ctFileBytes.sublist(8, 16);
Uint8List ciphertext = ctFileBytes.sublist(16);

// derive key and IV via password and salt
Uint8List passphrase = Uint8List.fromList(utf8.encode('my passphrase'));
Uint8List keyIv = deriveKeyIv(salt, passphrase);
Uint8List key = keyIv.sublist(0, 32);
Uint8List iv = keyIv.sublist(32);

// decrypt using AES-256, CBC mode
Uint8List decryptedText = decryptAesCbcPkcs7(ciphertext, key, iv);
File dtFile = File('<path to decrypted.txt file>');
await dtFile.writeAsBytes(decryptedText);

with

Uint8List decryptAesCbcPkcs7(Uint8List ciphertext, Uint8List key, Uint8List iv){
  PaddedBlockCipherImpl paddingCipher = PaddedBlockCipherImpl(PKCS7Padding(), CBCBlockCipher(AESEngine()))
    ..init(false, PaddedBlockCipherParameters(ParametersWithIV(KeyParameter(key), iv), null));
  return paddingCipher.process(ciphertext);
}
主站蜘蛛池模板: 精品久久久久久中文字幕一区| 亚洲欧美日韩一区二区三区在线| 国产精品分类视频分类一区| 色系一区二区三区四区五区 | 久久久无码精品人妻一区| 国模大胆一区二区三区| 亚洲一区二区三区日本久久九| 日韩精品一区二区三区中文字幕| 伊人久久精品一区二区三区| 人妻少妇精品一区二区三区| 夜夜精品无码一区二区三区| 国产精品一区二区资源| 蜜桃AV抽搐高潮一区二区| 日本视频一区在线观看免费| 亚洲AV日韩AV天堂一区二区三区 | 日本高清不卡一区| 合区精品久久久中文字幕一区 | 久草新视频一区二区三区| 亚洲AV无码一区二区三区在线观看 | 日本强伦姧人妻一区二区| 国产精品免费综合一区视频| 尤物精品视频一区二区三区| 无码人妻一区二区三区一| 中文字幕无线码一区2020青青| 2020天堂中文字幕一区在线观| 78成人精品电影在线播放日韩精品电影一区亚洲 | 狠狠综合久久av一区二区 | 国产精品一区二区久久精品无码 | 久久精品国产一区二区| 国产伦精品一区二区免费| 精品无码综合一区| 中文字幕AV一区中文字幕天堂| 中文字幕在线观看一区二区| 久久综合精品不卡一区二区| 无码欧精品亚洲日韩一区| 精品欧洲av无码一区二区| 亚洲国产成人久久综合一区 | 亚洲Aⅴ无码一区二区二三区软件| 一区二区三区杨幂在线观看| 精品久久国产一区二区三区香蕉 | 亚洲天堂一区二区|