signBytes abstract method
Sign data
with this RSASSA-PSS private key.
Returns a signature as a list of raw bytes. This uses the Hash
specified when the key was generated or imported. The length of the
salt is specified in bytes using saltLength
.
If the saltLength
is zero the signature is deterministic.
The saltLength
is typically zero or length of the Hash, for a
discussion of appropriate values for saltLength
see
RFC 3447 Section 9.1, Notes 4.
When running in Safari/WebKit on Mac the saltLength
is restricted to
0 <= saltLength <= hashLength
as the underlying cryptography libraries
follow FIPS 186-4, Section 5.5, Step (e).
Example
import 'dart:convert' show utf8, base64;
import 'package:webcrypto/webcrypto.dart';
import 'package:pem/pem.dart';
// Read prviate key data from PEM encoded block. This will remove the
// '----BEGIN...' padding, decode base64 and return encoded bytes.
List<int> keyData = PemCodec(PemLabel.privateKey).decode("""
-----BEGIN PRIVATE KEY-----
MIGEAgEAMBAGByqG...
-----END PRIVATE KEY-----
""");
// Import private key from binary PEM decoded data.
final privatKey = await RsaPssPrivateKey.importPkcs8Key(
keyData,
Hash.sha256,
);
// Use the same salt for signing and verifying.
// In this case we're using the length of the hash function, divided by 8
// to as saltLength must be specified in bytes.
const saltLength = 256 / 8;
// Create a signature for UTF-8 encoded message
final message = 'hello world';
final signature = await privateKey.signBytes(
utf8.encode(message),
saltLength,
);
print('signature: ${base64.encode(signature)}');
Implementation
// Notes on saltLength for maintainers:
// Source code for WebKit on Mac uses CommonCrypto:
// https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/crypto/mac/CryptoAlgorithmRSA_PSSMac.cpp?rev=238754#L56
// And CommonCrypto calls into corecrypto:
// https://opensource.apple.com/source/CommonCrypto/CommonCrypto-60165.120.1/lib/CommonRSACryptor.c.auto.html
// which references FIPS 186-4, Section 5.5, Step (e):
// https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
// limiting saltLength to 0 <= saltLength <= hashLength
// Note: saltLength and hashLength is given in bytes.
// Hence: hashLength = 256 / 8 is hash is sha256.
//
// It's unclear if a saltLength greater than hashLength has any practical
// uses, we'd probably have to digg further into the literature to find source
// we can quote. Most likely saltLength > hashLength is so obviously pointless
// that nobody every considered proving or saying anything about it.
// Which makes it hard for us to say that it's not useful.
//
// Note: Web Cryptography specification references RFC 3447, not FIPS 186-4.
Future<Uint8List> signBytes(List<int> data, int saltLength);