我有一个网站来加密和解密文件,我想创建一个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 代码中:
Salted__
的 ASCII 编码加上 8 字节的 Sals 加上密文。一个可能的实现是:
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);
与
Uint8List deriveKeyIv(Uint8List salt, Uint8List passphrase){
KeyDerivator derivator = KeyDerivator('SHA-256/HMAC/PBKDF2');
Pbkdf2Parameters params = Pbkdf2Parameters(salt, 10000, (256 + 128)~/8);
derivator.init(params);
return derivator.process(passphrase);
}
Uint8List encryptAesCbcPkcs7(Uint8List plaintext, Uint8List key, Uint8List iv){
CBCBlockCipher cipher = CBCBlockCipher(AESEngine());
ParametersWithIV<KeyParameter> params = ParametersWithIV<KeyParameter>(KeyParameter(key), iv);
PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, Null> paddingParams = PaddedBlockCipherParameters<ParametersWithIV<KeyParameter>, Null>(params, null);
PaddedBlockCipherImpl paddingCipher = PaddedBlockCipherImpl(PKCS7Padding(), cipher);
paddingCipher.init(true, paddingParams);
Uint8List ciphertext = paddingCipher.process(plaintext);
return ciphertext;
}
Uint8List concatAndEncode(Uint8List salt, Uint8List ciphertext){
BytesBuilder prefixSaltCiphertext = BytesBuilder();
prefixSaltCiphertext.add(utf8.encode('Salted__'));
prefixSaltCiphertext.add(salt);
prefixSaltCiphertext.add(ciphertext);
return prefixSaltCiphertext.toBytes();
}
以这种方式生成的密文可以使用发布的 OpenSSL 语句进行解密(顺便说一句,这是用于解密而不是加密)。
这里必须考虑到,OpenSSL 在早期版本中使用 MD5 作为默认数字,从 v1.1.0 开始使用 SHA256。上面的代码假设 SHA256。如果您有较旧的 OpenSSL 版本,您可以在 OpenSSL 语句中设置
-md sha256
。或者,代码必须适应 MD5。
对于加密,在 Dart 代码中:
实现方式类似于加密。