encrypt static method
Шифрует пакет данных, создавая PASETO v4.local токен.
Implementation
static Future<Payload> encrypt(
Package package, {
required SecretKey secretKey,
List<int>? implicit,
}) async {
// Получаем ключ для шифрования
final keyBytes = await secretKey.extractBytes();
// Проверяем размер ключа
if (keyBytes.length != keyLength) {
throw ArgumentError(
'Ключ должен быть $keyLength байт, получено: ${keyBytes.length}');
}
// Генерируем случайный nonce (32 байта)
final nonce = Uint8List(nonceLength);
final random = Random.secure();
for (var i = 0; i < nonceLength; i++) {
nonce[i] = random.nextInt(256);
}
// 1. Генерируем ключи шифрования (Ek) и аутентификации (Ak)
final encKeys = await _deriveKeys(keyBytes, nonce);
final encryptionKey = encKeys.encryptionKey;
final counterNonce = encKeys.counterNonce;
final authKey = encKeys.authKey;
// 2. Шифруем сообщение с помощью нашей реализации XChaCha20
// Создаем экземпляр нашей реализации XChaCha20
final xchacha = XChaCha20();
// Преобразуем входные данные в правильный формат
final keyParam = KeyParameter(Uint8List.fromList(encryptionKey));
// ВАЖНО: Для XChaCha20 нужен 24-байтный nonce
// Используем все 24 байта из counterNonce
final nonceBytes = Uint8List.fromList(counterNonce.sublist(0, 24));
// Инициализируем с ключом и nonce для шифрования
xchacha.init(true, ParametersWithIV<KeyParameter>(keyParam, nonceBytes));
// Шифруем данные
final cipherText = xchacha.process(Uint8List.fromList(package.content));
// 3. Подготавливаем данные для аутентификации (PAE)
final headerBytes = utf8.encode(header.toTokenString);
final implicitBytes = implicit ?? <int>[];
final footer = package.footer ?? <int>[];
// 4. PAE(h, n, c, f, i)
final preAuth = _pae([
headerBytes, // h - заголовок
nonce, // n - nonce
cipherText, // c - шифротекст
footer, // f - футер (опциональный)
implicitBytes, // i - implicit assertion (опциональный)
]);
// 5. Вычисляем BLAKE2b-MAC с помощью ключа аутентификации
final macBytes = _computeMac(preAuth, authKey);
final mac = Mac(macBytes);
// 6. Объединяем данные для токена
final secretBox = SecretBox(
cipherText,
nonce: nonceBytes,
mac: mac,
);
final payload = PayloadLocal(
nonce: Mac(nonce),
secretBox: secretBox,
mac: mac,
);
return payload;
}