| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- import 'dart:convert';
- import 'dart:math';
- import 'package:pointycastle/pointycastle.dart';
- import 'package:pointycastle/key_derivators/pbkdf2.dart';
- import 'package:pointycastle/digests/sha256.dart';
- import 'package:pointycastle/macs/hmac.dart';
- // 随机字符串
- String randomString(int len) {
- if (len <= 0) {
- len = 16;
- }
- // 安全字符集(去掉Base64中的特殊字符 + / =)
- const charset = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_-';
- final random = Random.secure();
- final result = StringBuffer();
- for (int i = 0; i < len; i++) {
- final index = random.nextInt(charset.length);
- result.write(charset[index]);
- }
- return result.toString();
- }
- String randomStringEx(int len, {
- final bool includeLowercase = true,
- final bool includeUppercase = true,
- final bool includeDigits = true,
- final bool includeSpecialChars = true,
- final String? customCharset,
- }) {
- if (len <= 0) {
- len = 16;
- }
- String? charset;
- if (customCharset != null) {
- charset = customCharset;
- } else {
- final buffer = StringBuffer();
- if (includeLowercase) buffer.write('abcdefghijklmnopqrstuvwxyz');
- if (includeUppercase) buffer.write('ABCDEFGHIJKLMNOPQRSTUVWXYZ');
- if (includeDigits) buffer.write('0123456789');
- if (includeSpecialChars) buffer.write('_-');
- charset = buffer.toString();
- }
- if (charset.isEmpty) {
- throw StateError('empty charset');
- }
- final random = Random.secure();
- final result = StringBuffer();
- for (int i = 0; i < len; i++) {
- final index = random.nextInt(charset.length);
- result.write(charset[index]);
- }
- return result.toString();
- }
- /// password to PBKDF2 password
- String passwordWithPBKDF2({
- required String password,
- required String salt,
- int iterations = 100000,
- int keyLength = 32,
- }) {
- final seed = utf8.encode(password);
- final saltBytes = utf8.encode(salt);
- // 1. 初始化 PBKDF2 派生器(HMAC-SHA256 作为伪随机函数)
- final pbkdf2 = PBKDF2KeyDerivator(
- HMac(SHA256Digest(), 64), // HMAC-SHA256,64字节块大小
- );
- // 2. 设置参数:盐值 + 迭代次数 + 密钥长度(AES-256 需要 32 字节)
- final params = Pbkdf2Parameters(
- saltBytes,
- iterations, // 迭代次数(越高越安全,建议 10万+)
- keyLength, // 输出密钥长度(32字节 = 256位,适配 AES-256)
- );
- pbkdf2.init(params);
- // 3. 派生密钥(返回 32 字节的 AES-256 密钥)
- final keyBytes = pbkdf2.process(seed);
- return base64Encode(keyBytes);
- }
- //
- // /// ---------- 使用 HMAC-SHA256 实现 PBKDF2 ----------
- // ///
- // /// - [password]: 用户密码(UTF-8 编码后的字节)
- // /// - [salt]: 盐(建议随机生成)
- // /// - [iterations]: 迭代次数(如 10000)
- // /// - [keyLength]: 派生密钥长度(字节,如 32 = 256 位)
- //
- // String generatePasswordWithPBKDF2({
- // required String password,
- // required String salt,
- // int iterations = 10000,
- // int keyLength = 32,
- // }) {
- // final key = base64.encode(pbkdf2HmacSha256(
- // password: utf8.encode(password),
- // salt: utf8.encode(salt),
- // iterations: iterations,
- // keyLength: keyLength,
- // ));
- // return key;
- // }
- //
- // Uint8List pbkdf2HmacSha256({
- // required Uint8List password,
- // required Uint8List salt,
- // int iterations = 100000,
- // int keyLength = 32,
- // }) {
- // if (iterations < 1) throw ArgumentError('Iterations must be >= 1');
- // if (keyLength <= 0) throw ArgumentError('Key length must be > 0');
- //
- // final List<int> derivedKey = [];
- // final int hLen = 32; // SHA-256 输出长度(字节)
- // final int l = (keyLength + hLen - 1) ~/ hLen; // 块数
- //
- // for (int i = 1; i <= l; i++) {
- // // T_i = F(Password, Salt, Iterations, i)
- // final blockSalt = _concat(salt, _encodeInt(i));
- // final Uint8List u = hmacSha256(password, blockSalt);
- // Uint8List t = u;
- //
- // for (int j = 1; j < iterations; j++) {
- // final Uint8List uNext = hmacSha256(password, u);
- // t = _xor(t, uNext);
- // u.setAll(0, uNext); // 更新 u 为 uNext
- // }
- //
- // derivedKey.addAll(t);
- // }
- //
- // return Uint8List.fromList(derivedKey.sublist(0, keyLength));
- // }
- //
- // // HMAC-SHA256 辅助函数
- // Uint8List hmacSha256(Uint8List key, Uint8List data) {
- // final hmac = Hmac(sha256, key);
- // final digest = hmac.convert(data);
- // return Uint8List.fromList(digest.bytes);
- // }
- //
- // // 将整数编码为大端 4 字节(符合 RFC 2898)
- // Uint8List _encodeInt(int i) {
- // return Uint8List.fromList([
- // (i >> 24) & 0xFF,
- // (i >> 16) & 0xFF,
- // (i >> 8) & 0xFF,
- // i & 0xFF,
- // ]);
- // }
- //
- // // 拼接两个 Uint8List
- // Uint8List _concat(Uint8List a, Uint8List b) {
- // final result = Uint8List(a.length + b.length);
- // result.setAll(0, a);
- // result.setAll(a.length, b);
- // return result;
- // }
- //
- // // 按字节异或两个等长 Uint8List
- // Uint8List _xor(Uint8List a, Uint8List b) {
- // if (a.length != b.length) {
- // throw ArgumentError('XOR requires equal-length inputs');
- // }
- // final result = Uint8List(a.length);
- // for (int i = 0; i < a.length; i++) {
- // result[i] = a[i] ^ b[i];
- // }
- // return result;
- // }
|