46 lines
1.4 KiB
Dart
46 lines
1.4 KiB
Dart
import 'dart:convert';
|
|
|
|
import 'package:cryptography/cryptography.dart';
|
|
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
|
|
|
class ClientIdentity {
|
|
const ClientIdentity({required this.keyPair, required this.publicKey});
|
|
|
|
final SimpleKeyPair keyPair;
|
|
final SimplePublicKey publicKey;
|
|
}
|
|
|
|
class IdentityStore {
|
|
IdentityStore({FlutterSecureStorage? storage})
|
|
: _storage = storage ?? const FlutterSecureStorage();
|
|
|
|
static const _seedKey = 'ed25519_seed_v1';
|
|
final FlutterSecureStorage _storage;
|
|
final Ed25519 _algorithm = Ed25519();
|
|
|
|
Future<ClientIdentity> loadOrCreate() async {
|
|
final encoded = await _storage.read(key: _seedKey);
|
|
final SimpleKeyPair keyPair;
|
|
if (encoded == null) {
|
|
keyPair = await _algorithm.newKeyPair();
|
|
final seed = await keyPair.extractPrivateKeyBytes();
|
|
await _storage.write(key: _seedKey, value: base64Encode(seed));
|
|
} else {
|
|
final seed = base64Decode(encoded);
|
|
if (seed.length != 32) {
|
|
throw StateError('invalid stored Ed25519 seed');
|
|
}
|
|
keyPair = await _algorithm.newKeyPairFromSeed(seed);
|
|
}
|
|
return ClientIdentity(
|
|
keyPair: keyPair,
|
|
publicKey: await keyPair.extractPublicKey(),
|
|
);
|
|
}
|
|
|
|
Future<List<int>> sign(ClientIdentity identity, List<int> payload) async {
|
|
final signature = await _algorithm.sign(payload, keyPair: identity.keyPair);
|
|
return signature.bytes;
|
|
}
|
|
}
|