mirror of
https://github.com/GitJournal/GitJournal.git
synced 2025-07-18 03:10:28 +08:00
125 lines
2.9 KiB
Dart
125 lines
2.9 KiB
Dart
import 'dart:async';
|
|
import 'dart:convert';
|
|
|
|
import 'package:crypton/crypton.dart';
|
|
import 'package:isolate/isolate_runner.dart';
|
|
import 'package:meta/meta.dart';
|
|
import 'package:ssh_key/ssh_key.dart' as ssh_key;
|
|
|
|
import 'package:gitjournal/error_reporting.dart';
|
|
import 'package:gitjournal/ssh/binary_length_value.dart';
|
|
import 'package:gitjournal/utils/logger.dart';
|
|
|
|
class RsaKeyPair {
|
|
RSAPublicKey publicKey;
|
|
RSAPrivateKey privateKey;
|
|
|
|
RsaKeyPair.fromStrings({
|
|
@required String privateKey,
|
|
@required String publicKey,
|
|
}) {
|
|
publicKey = publicKey.trim();
|
|
try {
|
|
var key = ssh_key.publicKeyDecode(publicKey);
|
|
if (key is ssh_key.RSAPublicKeyWithInfo) {
|
|
this.publicKey = RSAPublicKey(key.modulus, key.exponent);
|
|
}
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
|
|
if (publicKey == null) {
|
|
try {
|
|
this.publicKey = RSAPublicKey.fromString(publicKey);
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
}
|
|
|
|
try {
|
|
var key = ssh_key.privateKeyDecode(privateKey);
|
|
if (key is ssh_key.RSAPrivateKeyWithInfo) {
|
|
this.privateKey =
|
|
RSAPrivateKey(key.modulus, key.exponent, key.p, key.q);
|
|
}
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
|
|
if (privateKey == null) {
|
|
try {
|
|
this.privateKey = RSAPrivateKey.fromPEM(privateKey);
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
}
|
|
|
|
if (privateKey == null) {
|
|
try {
|
|
this.privateKey = RSAPrivateKey.fromString(privateKey);
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
RsaKeyPair.generate() {
|
|
var keyPair = RSAKeypair.fromRandom(keySize: 4096);
|
|
|
|
publicKey = keyPair.publicKey;
|
|
privateKey = keyPair.privateKey;
|
|
}
|
|
|
|
// Tries to encrypt and decrypt
|
|
bool isValid() {
|
|
if (publicKey == null || privateKey == null) {
|
|
return false;
|
|
}
|
|
var orig = 'word';
|
|
var enc = publicKey.encrypt(orig);
|
|
var dec = privateKey.decrypt(enc);
|
|
|
|
return orig == dec;
|
|
}
|
|
|
|
// OpenSSH Public Key (single-line format)
|
|
String publicKeyString({String comment = ""}) {
|
|
var pk = publicKey.asPointyCastle;
|
|
|
|
var data = BinaryLengthValue.encode([
|
|
BinaryLengthValue.fromString("ssh-rsa"),
|
|
BinaryLengthValue.fromBigInt(pk.exponent),
|
|
BinaryLengthValue.fromBigInt(pk.modulus),
|
|
]);
|
|
|
|
if (comment.isNotEmpty) {
|
|
comment = comment.replaceAll('\r', ' ');
|
|
comment = comment.replaceAll('\n', ' ');
|
|
comment = ' $comment';
|
|
}
|
|
|
|
return 'ssh-rsa ${base64.encode(data)}$comment';
|
|
}
|
|
|
|
String privateKeyString() {
|
|
return privateKey.toPEM();
|
|
}
|
|
|
|
static Future<RsaKeyPair> generateAsync() async {
|
|
IsolateRunner iso = await IsolateRunner.spawn();
|
|
try {
|
|
return await iso.run(_gen, null);
|
|
} catch (e) {
|
|
Log.e(e);
|
|
logException(e, StackTrace.current);
|
|
return null;
|
|
} finally {
|
|
iso.close();
|
|
}
|
|
}
|
|
}
|
|
|
|
FutureOr<RsaKeyPair> _gen(void _) async {
|
|
return RsaKeyPair.generate();
|
|
}
|