sign method
Future<String>
sign({
- dynamic data,
- WalletStore? wallet,
- String? did,
- Map<
String, dynamic> ? jwk, - bool detached = false,
- dynamic jwsHeader,
override
Build a (detached) JWS
Either using a combination of wallet
and did
or by using a private JsonWebKey jwk
.
Implementation
@override
Future<String> sign(
{dynamic data,
WalletStore? wallet,
String? did,
Map<String, dynamic>? jwk,
bool detached = false,
dynamic jwsHeader}) async {
String header;
if (jwsHeader != null) {
Map<String, dynamic>? headerMap;
if (jwsHeader is String) {
headerMap = jsonDecode(jwsHeader);
} else {
headerMap = jwsHeader;
}
if (headerMap!['alg'] != 'ES256K-R') {
throw Exception('Unsupported signature algorithm ${headerMap['alg']}');
}
header = removePaddingFromBase64(
base64UrlEncode(utf8.encode(jsonEncode(headerMap))));
} else {
var critical = <String, dynamic>{};
critical['b64'] = false;
header = removePaddingFromBase64(
buildJwsHeader(alg: 'ES256K-R', extra: critical));
}
String signable = '';
if (data is String) {
signable = data;
} else if (data is Map<String, dynamic>) {
signable = jsonEncode(data);
} else {
throw Exception('Unexpected Datatype ${data.runtimeType} for toSign');
}
var payload =
removePaddingFromBase64(base64UrlEncode(utf8.encode(signable)));
var signingInput = '$header.$payload';
var hash = sha256.convert(ascii.encode(signingInput)).bytes;
String? privateKeyHex;
if (did != null && wallet != null) {
privateKeyHex = await wallet.getPrivateKeyForCredentialDid(did);
privateKeyHex ??= await wallet.getPrivateKeyForConnectionDid(did);
if (privateKeyHex == null) throw Exception('Could not find private key');
} else if (jwk != null) {
if (jwk['crv'] != 'secp256k1') {
throw Exception('Wrong crv value for private key');
}
if (jwk['d'] == null) {
throw Exception('This is no private key');
}
privateKeyHex = hexEncode(
Uint8List.fromList(base64Decode(addPaddingToBase64(jwk['d']))));
} else {
throw Exception('No private key given. Can\'t sign data');
}
var key = EthPrivateKey.fromHex(privateKeyHex);
var sigArray = _buildSignatureArray(hash as Uint8List, key);
while (sigArray.length != 65) {
sigArray = _buildSignatureArray(hash, key);
}
if (detached) {
return '$header.'
'.${removePaddingFromBase64(base64UrlEncode(sigArray))}';
} else {
return '$header.$payload'
'.${removePaddingFromBase64(base64UrlEncode(sigArray))}';
}
}