87 lines
2.2 KiB
Dart
87 lines
2.2 KiB
Dart
import 'dart:convert';
|
|
import 'dart:typed_data';
|
|
|
|
import 'package:dart_spectre/src/scope.dart';
|
|
import 'package:dart_spectre/src/template.dart';
|
|
import "package:pointycastle/export.dart";
|
|
|
|
final scrypt = Scrypt();
|
|
final hmac = HMac(SHA256Digest(), 64);
|
|
|
|
class Spectre {
|
|
final String _name;
|
|
final String _secret;
|
|
late Scoper _scoper;
|
|
|
|
late Uint8List _key;
|
|
|
|
Spectre(this._name, this._secret, [Scoper? scoper]) {
|
|
_scoper = scoper ?? defaultScoper;
|
|
_key = _userKey();
|
|
}
|
|
|
|
Uint8List _userKey() {
|
|
var nameBytes = utf8.encode(_name);
|
|
var secretBytes = utf8.encode(_secret);
|
|
var keyScope = utf8.encode(_scoper.scope(Scope.authentication));
|
|
|
|
var nameBytesLen = nameBytes.length;
|
|
var keySalt = keyScope +
|
|
List.from([
|
|
nameBytesLen >> 24,
|
|
nameBytesLen >> 16,
|
|
nameBytesLen >> 8,
|
|
nameBytesLen,
|
|
]) +
|
|
nameBytes;
|
|
|
|
scrypt.init(ScryptParameters(32768, 8, 2, 64, Uint8List.fromList(keySalt)));
|
|
return scrypt.process(Uint8List.fromList(secretBytes));
|
|
}
|
|
|
|
Uint8List _siteKey(String name, int counter, Scope scope) {
|
|
var nameBytes = utf8.encode(name);
|
|
var scopeBytes = utf8.encode(_scoper.scope(scope));
|
|
|
|
var nameBytesLen = nameBytes.length;
|
|
var keySalt = scopeBytes +
|
|
List.from([
|
|
nameBytesLen >> 24,
|
|
nameBytesLen >> 16,
|
|
nameBytesLen >> 8,
|
|
nameBytesLen,
|
|
]) +
|
|
nameBytes +
|
|
List.from([
|
|
counter >> 24,
|
|
counter >> 16,
|
|
counter >> 8,
|
|
counter,
|
|
]);
|
|
|
|
hmac.init(KeyParameter(_key));
|
|
return hmac.process(Uint8List.fromList(keySalt));
|
|
}
|
|
|
|
String site(String siteName,
|
|
{Template? templateType,
|
|
int counter = 1,
|
|
Scope scope = Scope.authentication}) {
|
|
templateType = templateType ?? scopeDefaultTemplate(scope);
|
|
|
|
var siteKey = _siteKey(siteName, counter, scope);
|
|
|
|
var templateSet = templates[templateType]!;
|
|
var template = templateSet[siteKey[0] % templateSet.length];
|
|
|
|
var out = StringBuffer();
|
|
var idx = 0;
|
|
for (var rune in template.runes) {
|
|
var chars = characters[String.fromCharCode(rune)]!;
|
|
var char = chars[siteKey[++idx] % chars.length];
|
|
out.write(char);
|
|
}
|
|
return out.toString();
|
|
}
|
|
}
|