Message Validation

Underpinning MintChip message validation is a PKI(Public Key Infrastructure). The Royal Canadian Mint creates MintChip devices and looks after the MintChip Certificate Authorities(CA).

When both the Sender's and Receiver's MintChip devices are present the Receiver's MintChip will reject a value message if it has been tampered with, or is a duplicate of a previously credited value message.

This section on message validation describes how you can validate a value message when a MintChip device is not present.

A typical scenario is an online merchant selling instant access content, using a co-located or virtual server which will not facilitate a MintChip device.

MintChip value messages use RSA SHA-1 digital signatures, a cryptographic standard to ensure authenticity of a message. Using the MintChip Certificate Authority(CA) certificates, it is possible for the Receiver to check for authentic value messages without a MintChip device. The Merchant is able to batch load value messages when convenient.

There are five main tasks for the server to perform to check a MintChip value message's authenticity.

  1. Message Sanity tests
  2. Verify Sender Certificate
  3. Verify Value Message
  4. Challenge Check
  5. Parameter Check

Code samples are provided in the server scripting language PHP using PHP's OpenSSL cryptographic extension Module.

Message Sanity tests

Before doing any kind of processor intensive cryptographic function, it is good practice to filter out the junk by doing some simple sanity tests. After unpacking an incoming MintChip value message, I have taken the data element Sender-cert, which is the Sender's X.509 certificate and read the issuer's organisation text.

//PHP Openssl requires certificates to be in formatted to the PEM standard. 
$PEM-sender-cert = der2pem($DER-sender-cert);

$Cert-info = openssl_x509_parse($PEM-sender-cert);

if($Cert-info['issuer']['O'] != 'Royal Canadian Mint'){
        echo "Sanity test failed";

Verify Sender Certificate

Next check the Sender's certificate was signed by one of the three MintChip CA certificates.

//check issued by mint ss0

$CApaths = array($path . "/certs/RCMSS0.pem", $path . "/certs/RCMSS1.pem", $path . "/certs/RCMSS2.pem"); //Requires Full path

$res = openssl_x509_checkpurpose($PEM-sender-cert, X509_PURPOSE_ANY, $CApaths);

if(!(($res === True) or ($res === 1))) {
        echo "Issuer check failed";

Verify Value Message

To ensure the value message has not been tampered with, we need the signature with the value message and also build a special data element called the Value Transfer Message Plain-text Field (VTMPF).

Value Transfer Message Plain-text Field (52 octets)
Version (1 octet) Sender ID (8 octets) Receiver ID (8 octets) Currency (1 octet) Value (3 octets) Challenge (4 octets) Date/Time (3 octets) Tac (24 octets)

Above shows the eight data elements which are concatenated together to form the VTMPF. The VTMPF is exactly 52 octets and is not DER encoded.

//mintchip_parse - Parse a DER encoded MintChip or MintChip Request message and return the information as an array

$MC-Value-Info = mintchip_parse($MC-Value);

$Signature = $MC-Value-Info["vm-resp"]["value-message"]["signature"];

$VTMPF= $MC-Value-Info["vm-resp"]["value-message"]["secure-element-version"] .
        $MC-Value-Info["vm-resp"]["value-message"]["payer-id"] .
        $MC-Value-Info["vm-resp"]["value-message"]["payee-id"] .
        $MC-Value-Info["vm-resp"]["value-message"]["currency"] .
        $MC-Value-Info["vm-resp"]["value-message"]["value"] .
        $MC-Value-Info["vm-resp"]["value-message"]["challenge"] .
        $MC-Value-Info["vm-resp"]["value-message"]["datetime"] .

$pubkeyid = openssl_get_publickey($PEM-sender-cert);

$ok = openssl_verify($VTMPF, $Signature, $pubkeyid);

if ($ok == 1) echo "Data elements have not been tampered with.";

Challenge Check

When the Receiver's MintChip is not present, we also need a process to check for duplicate MintChip values messages. One of the data elements within both the MintChip request and value messages is the Challenge.

The Challenge is a random number generated by the Receiver with enough entropy to ensure it's never generated twice for the same amount to the same Receiver. The Receiver passes the Challenge within the MintChip request message, and the Sender uses the same number for the Challenge within its MintChip value response message. The Receiver only accepts MintChip value response messages which pair with a request.

Parameter Check

The last of the five tasks is to check the remaining data elements of the received MintChip value message. The Receiver ID must match the intended ID of the recipient. The Value and Currency must be for the correct amount, in a currency the Receiver can handle.