2019-07-04 21:45:05 +00:00
|
|
|
import 'dart:math';
|
|
|
|
import 'dart:convert';
|
|
|
|
|
|
|
|
import 'package:crypt/crypt.dart';
|
2019-07-09 02:03:44 +00:00
|
|
|
import 'package:encrypt/encrypt.dart';
|
|
|
|
import 'package:password_hash/password_hash.dart';
|
2019-07-04 21:45:05 +00:00
|
|
|
|
|
|
|
String hashPassword(String password) {
|
2019-07-09 02:03:44 +00:00
|
|
|
const saltSize = 16;
|
|
|
|
const saltIntMax = 256;
|
|
|
|
|
2019-07-04 21:45:05 +00:00
|
|
|
final random = Random.secure();
|
2019-07-09 02:03:44 +00:00
|
|
|
final saltInts =
|
2019-07-13 19:48:32 +00:00
|
|
|
List<int>.generate(saltSize, (_) => random.nextInt(saltIntMax));
|
2019-07-04 21:45:05 +00:00
|
|
|
final salt = base64.encode(saltInts);
|
|
|
|
|
|
|
|
return Crypt.sha256(password, salt: salt).toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool matchHashedPassword(String hashedPassword, String password) =>
|
|
|
|
Crypt(hashedPassword).match(password);
|
2019-07-09 02:03:44 +00:00
|
|
|
|
2019-07-13 19:48:32 +00:00
|
|
|
String decryptPassword(String masterpass, privateKey, cipherText) {
|
|
|
|
final key = PBKDF2().generateKey(
|
|
|
|
masterpass, privateKey, pbkdf2Rounds, keySize,
|
|
|
|
);
|
2019-07-09 02:03:44 +00:00
|
|
|
|
2019-07-13 19:48:32 +00:00
|
|
|
var cipherBytes = base64.decode(cipherText);
|
|
|
|
final ivBytes = cipherBytes.sublist(0, aesBlockSize);
|
|
|
|
cipherBytes = cipherBytes.sublist(aesBlockSize);
|
2019-07-09 02:03:44 +00:00
|
|
|
|
2019-07-13 19:48:32 +00:00
|
|
|
final iv = IV(ivBytes);
|
2019-07-09 02:03:44 +00:00
|
|
|
final encrypter = Encrypter(AES(Key(key), mode: AESMode.cbc));
|
2019-07-13 19:48:32 +00:00
|
|
|
return encrypter.decrypt(Encrypted(cipherBytes), iv: iv);
|
2019-07-09 02:03:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const pbkdf2Rounds = 4096;
|
|
|
|
const keySize = 32;
|
|
|
|
const aesBlockSize = 16;
|