Sample code for 30+ languages & platforms
Dart

ECDSA Sign Data and Get Raw R and S Values

See more ECC Examples

Demonstrates getting the raw R and S value of an ECDSA signature.

Chilkat Dart Downloads

Dart
import 'package:chilkat/chilkat.dart';

void main() {
  // This example requires the Chilkat API to have been previously unlocked.
  // See Global Unlock Sample for sample code.

  // To create an ECDSA signature, the data first needs to be hashed.  Then the hash
  // is signed.

  final crypt = CkCrypt2();
  crypt.hashAlgorithm = 'SHA256';
  crypt.charset = 'utf-8';
  crypt.encodingMode = 'base64';

  // Hash a string.
  final hash1 = crypt.hashStringENC('The quick brown fox jumps over the lazy dog');
  print('hash1 = $hash1');

  // -----------------------------------------------------------
  // An ECDSA private key is used for signing.  The public key is for signature verification.
  // Load our ECC private key.
  // Our private key file contains this:

  // 	// -----BEGIN PRIVATE KEY-----
  // 	MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg3J8q/24D1sEKGdP9
  // 	72MGYElLGpw/a56Y3t6pfON3uhShRANCAATlSmoizyhAwoYZAOuFBATl07/1RR54
  // 	a1Dzfm16grxJe666AGKR+bSs24hk7TEpaeCTvT8YOOM3l+xKFg7zq6Q9
  // 	-----END PRIVATE KEY-----

  final privKey = CkPrivateKey();
  try {
    privKey.loadPemFile('qa_data/ecc/secp256r1-key-pkcs8.pem');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // Sign the hash..
  final prng = CkPrng();
  final ecdsa = CkEcc();
  final String ecdsaSigBase64;
  try {
    ecdsaSigBase64 = ecdsa.signHashENC(hash1, 'base64', privKey, prng);
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // The ECDSA signature is ASN.1 that contains a sequence of 2 large integers (r and s)
  // For example:
  // SEQUENCE (2 elem)
  //   INTEGER (255 bit) 792134D9B4AD82D5431ED03835A88E2596EB35E5B13054BD9B05A0069281ACC9
  //   INTEGER (255 bit) 481E758CC1E3CBF825537EC3D9A2CA627E5FAD1137BBEA65DF38658DCB0A9ED5

  print('Base64 ECDSA signature = $ecdsaSigBase64');

  // If the raw R and S values are needed, here's how to get them:
  final asn = CkAsn();
  try {
    asn.loadEncoded(ecdsaSigBase64, 'base64');
  } on ChilkatException catch (e) {
    print(e.lastErrorText);
    return;
  }

  // The R and X will be in hexidecimal in the XML.
  final xml = CkXml();
  xml.loadXml(asn.asnToXml());
  print(xml.getXml());

  // The XML looks like this:
  // <sequence>
  // <int>792134D9B4AD82D5431ED03835A88E2596EB35E5B13054BD9B05A0069281ACC9</int>
  // <int>481E758CC1E3CBF825537EC3D9A2CA627E5FAD1137BBEA65DF38658DCB0A9ED5</int>
  // </sequence>

  // Copy raw R and S hex values into a Chilkat BinData object.
  final bd = CkBinData();
  final r = xml.getChildContent('int[0]');
  final s = xml.getChildContent('int[1]');
  bd.appendEncoded(r, 'hex');
  bd.appendEncoded(s, 'hex');

  print('Number of bytes in bd: ${bd.numBytes}');
}