You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.7 KiB
93 lines
2.7 KiB
import 'dart:typed_data'; |
|
|
|
import 'package:pointycastle/export.dart'; |
|
|
|
/// https://gist.github.com/proteye/e54eef1713e1fe9123d1eb04c0a5cf9b |
|
class AesHelper { |
|
static const CBC_MODE = 'CBC'; |
|
static const CFB_MODE = 'CFB'; |
|
|
|
// AES key size |
|
static const KEY_SIZE = 32; // 32 byte key for AES-256 |
|
static const ITERATION_COUNT = 1000; |
|
|
|
static Uint8List deriveKey( |
|
Uint8List password, { |
|
Uint8List salt, |
|
int iterationCount = ITERATION_COUNT, |
|
int derivedKeyLength = KEY_SIZE, |
|
}) { |
|
final Pbkdf2Parameters params = |
|
Pbkdf2Parameters(salt, iterationCount, derivedKeyLength); |
|
final KeyDerivator keyDerivator = |
|
PBKDF2KeyDerivator(HMac(SHA256Digest(), 64)); |
|
keyDerivator.init(params); |
|
|
|
return keyDerivator.process(password); |
|
} |
|
|
|
static String decrypt(Uint8List derivedKey, Uint8List cipherIvBytes, |
|
{String mode = CBC_MODE}) { |
|
// Uint8List derivedKey = deriveKey(password); |
|
final KeyParameter keyParam = KeyParameter(derivedKey); |
|
final BlockCipher aes = AESFastEngine(); |
|
|
|
// Uint8List cipherIvBytes = base64.decode(ciphertext); |
|
final Uint8List iv = Uint8List(aes.blockSize) |
|
..setRange(0, aes.blockSize, cipherIvBytes); |
|
|
|
BlockCipher cipher; |
|
final ParametersWithIV params = ParametersWithIV(keyParam, iv); |
|
switch (mode) { |
|
case CBC_MODE: |
|
cipher = CBCBlockCipher(aes); |
|
break; |
|
case CFB_MODE: |
|
cipher = CFBBlockCipher(aes, aes.blockSize); |
|
break; |
|
default: |
|
throw ArgumentError('incorrect value of the "mode" parameter'); |
|
break; |
|
} |
|
cipher.init(false, params); |
|
|
|
final int cipherLen = cipherIvBytes.length - aes.blockSize; |
|
final Uint8List cipherBytes = Uint8List(cipherLen) |
|
..setRange(0, cipherLen, cipherIvBytes, aes.blockSize); |
|
final Uint8List paddedText = processBlocks(cipher, cipherBytes); |
|
final Uint8List textBytes = unpad(paddedText); |
|
|
|
return String.fromCharCodes(textBytes); |
|
} |
|
|
|
static Uint8List unpad(Uint8List src) { |
|
final pad = PKCS7Padding(); |
|
pad.init(null); |
|
|
|
final int padLength = pad.padCount(src); |
|
final int len = src.length - padLength; |
|
|
|
return Uint8List(len)..setRange(0, len, src); |
|
} |
|
|
|
static Uint8List pad(Uint8List src, int blockSize) { |
|
final pad = PKCS7Padding(); |
|
pad.init(null); |
|
|
|
final padLength = blockSize - (src.length % blockSize); |
|
final out = Uint8List(src.length + padLength)..setAll(0, src); |
|
pad.addPadding(out, src.length); |
|
|
|
return out; |
|
} |
|
|
|
static Uint8List processBlocks(BlockCipher cipher, Uint8List inp) { |
|
final out = Uint8List(inp.lengthInBytes); |
|
|
|
for (var offset = 0; offset < inp.lengthInBytes;) { |
|
offset += cipher.processBlock(inp, offset, out, offset); |
|
} |
|
|
|
return out; |
|
} |
|
}
|
|
|