signBytes abstract method

Future<Uint8List> signBytes(
  1. List<int> data,
  2. int saltLength
)

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);