

# Generate and verify MAC
<a name="crypto-ops-mac"></a>

Message Authentication Codes (MAC) are typically used to authenticate the integrity of a message (whether it's been modified). Cryptographic hashes such as HMAC (Hash-Based Message Authentication Code), CBC-MAC and CMAC (Cipher-based Message Authentication Code) provide additional assurance of the sender of the MAC by utilizing cryptography. HMAC is based on hash functions while CMAC is based on block ciphers. The service also supports ISO9797 Algorithms 1 and 3 which are types of CBC-MACs. 

All MAC algorithms of this service combine a cryptographic hash function and a shared secret key. They take a message and a secret key, such as the key material in a key, and return a unique tag or mac. If even one character of the message changes, or if the secret key changes, the resulting tag is entirely different. By requiring a secret key, cryptographic MACs also provides authenticity; it is impossible to generate an identical mac without the secret key. Cryptographic MACs are sometimes called symmetric signatures, because they work like digital signatures, but use a single key for both signing and verification. 

AWS Payment Cryptography supports several types of MACs:

**ISO9797 ALGORITHM 1**  
Denoted by `KeyUsage` of ISO9797\$1ALGORITHM1. If the field isn't a multiple of block size (8 bytes/16 hex characters for TDES, 16 bytes/32 characters for AES, AWS Payment Cryptography automatically applies ISO9797 Padding Method 1. If other padding methods are needed, you can apply them prior to calling the service.

**ISO9797 ALGORITHM 3 (Retail MAC)**  
Denoted by `KeyUsage` of ISO9797\$1ALGORITHM3. The same padding rules apply as Algorithm 1

**ISO9797 ALGORITHM 5 (CMAC)**  
Denoted by `KeyUsage` of TR31\$1M6\$1ISO\$19797\$15\$1CMAC\$1KEY

**HMAC**  
Denoted by `KeyUsage` of TR31\$1M7\$1HMAC\$1KEY including HMAC\$1SHA224, HMAC\$1SHA256, HMAC\$1SHA384 and HMAC\$1SHA512

**AS2805.4.1 MAC**  
Denoted by `KeyUsage` of TR31\$1M0\$1ISO\$116609\$1MAC\$1KEY. For more details on AS2805, see [AS2805](advanced.regional.as2805.md)

**DUKPT MAC**  
DUKPT MAC is typically used to confirm the source and payload of messages to/from payment terminals. It derives a key using DUKPT derivation techniques and then performs the MAC. Keys used with this option are denoted by a `KeyUsage` of TR31\$1B0\$1BASE\$1DERIVATION\$1KEY. 

**EMV MAC**  
EMV MAC is typically referred to as an integrity key in EMV documentation. It derives a key using EMV derivation techniques and then utilizes ISO9797\$1ALGORITHM3 internally. It is typically used to send issuer scripts to a chip card for reprogramming. Keys used with this option are denoted by a `KeyUsage` of TR31\$1E2\$1EMV\$1MKEY\$1INTEGRITY. If you are both sending a script and update an offline pin, see [GenerateMacEmvPinChange](https://docs.aws.amazon.com/payment-cryptography/latest/DataAPIReference/API_GenerateMacEmvPinChange) that performs both of these operations. 

**Topics**
+ [Generate MAC](generate-mac.md)
+ [Verify MAC](verify-mac.md)

# Generate MAC
<a name="generate-mac"></a>

Generate MAC API is used to authenticate card-related data, such as track data from a card magnetic stripe, by using known cryptographic keys to generate a MAC (Message Authentication Code) for data validation between sending and receiving parties. The data used to generate MAC includes message data, secret MAC encryption key and MAC algorithm to generate a unique MAC value for transmission. The receiving party of the MAC will use the same MAC message data, MAC encryption key, and algorithm to reproduce another MAC value for comparison and data authentication. Even if one character of the message changes or the MAC key used for verification is not identical, the resulting MAC value is different. The API supports ISO 9797-1 Algorithm 1 and ISO 9797-1 Algorithm 3 MAC (using a static MAC key and a derived DUKPT key), HMAC and EMV MAC encryption keys for this operation.

The input value for `message-data` must be hexBinary data.

For more information on all options for this API, see [GenerateMac](https://docs.aws.amazon.com/payment-cryptography/latest/DataAPIReference/API_GenerateMac.html) and [VerifyMac](https://docs.aws.amazon.com/payment-cryptography/latest/DataAPIReference/API_VerifyMac.html).

The optional parameter mac-length allows you to truncate the output value (although this can also be done within your code). A length of 8 refers to 8 bytes or 16 hex characters.

MAC keys can either be created with AWS Payment Cryptography by calling [CreateKey](https://docs.aws.amazon.com/payment-cryptography/latest/APIReference/API_CreateKey.html) or imported by calling [ImportKey](https://docs.aws.amazon.com/payment-cryptography/latest/APIReference/API_ImportKey.html). 

**Note**  
CMAC and HMAC algorithms don't require padding. All others require that the data be padded to the block size of the algorithm, which is multiples of 8 bytes (16 hex characters) for TDES and 16 bytes (32 hex characters) for AES. 

**Topics**
+ [Generate HMAC](#generate-mac-hmac)
+ [Generate MAC using ISO 9797-1 Algorithm 3](#generate-mac-iso9797-alg3)
+ [Generate MAC using CMAC](#generate-mac-cmac)
+ [Generate MAC using DUKPT CMAC](#generate-mac-dukpt-cmac)

## Generate HMAC
<a name="generate-mac-hmac"></a>

In this example, we will generate a HMAC (Hash-Based Message Authentication Code) for card data authentication using HMAC algorithm `HMAC_SHA256` and HMAC encryption key. The key must have KeyUsage set to `TR31_M7_HMAC_KEY` and KeyModesOfUse to `Generate`. The hash length (e.g. 256) is defined when the key is created and cannot be modified. 

The optional mac-length parameter will trim the output MAC, although this can be performed outside the service as well. This value is in bytes, so a value of 16 will expect a hex string of length 32.

**Example**  

```
$ aws payment-cryptography-data generate-mac \ 
    --key-identifier arn:aws:payment-cryptography:us-east-2:111122223333:key/qnobl5lghrzunce6 \ 
    --message-data "3b313038383439303031303733393431353d32343038323236303030373030303f33" \
    --generation-attributes Algorithm=HMAC
```

```
           
{
    "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/qnobl5lghrzunce6",
    "KeyCheckValue": "2976E7",
    "Mac": "ED87F26E961C6D0DDB78DA5038AA2BDDEA0DCE03E5B5E96BDDD494F4A7AA470C"
}
```

## Generate MAC using ISO 9797-1 Algorithm 3
<a name="generate-mac-iso9797-alg3"></a>

In this example, we will generate a MAC using ISO 9797-1 Algorithm 3 (Retail MAC) for card data authentication. The key must have KeyUsage set to `TR31_M3_ISO_9797_3_MAC_KEY` and KeyModesOfUse to `Generate`. 

**Example**  

```
$ aws payment-cryptography-data generate-mac \ 
    --key-identifier arn:aws:payment-cryptography:us-east-2:111122223333:key/kwapwa6qaifllw2h \ 
    --message-data "3b313038383439303031303733393431353d32343038323236303030373030303f33" \ 
    --generation-attributes="Algorithm=ISO9797_ALGORITHM3"
```

```
           
{
    "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/kwapwa6qaifllw2h",
    "KeyCheckValue": "2976EA",
    "Mac": "A8F7A73DAF87B6D0"
}
```

## Generate MAC using CMAC
<a name="generate-mac-cmac"></a>

CMAC is most commonly used when the keys are AES but it also supports TDES. In this example, we will generate a MAC using CMAC (ISO 9797-1 Algorithm 5) for card data authentication with an AES key. The key must have KeyUsage set to `TR31_M6_ISO_9797_5_CMAC_KEY` and KeyModesOfUse to `Generate`. 

**Example**  

```
$ aws payment-cryptography-data generate-mac \ 
    --key-identifier arn:aws:payment-cryptography:us-east-2:111122223333:key/tqv5yij6wtxx64pi \ 
    --message-data "3b313038383439303031303733393431353d32343038323236303030373030303f33" \ 
    --generation-attributes Algorithm="CMAC"
```

```
           
{
    "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/tqv5yij6wtxx64pi",
    "KeyCheckValue": "C1EB8F",
    "Mac": "1F8C36E63F91E4E93DF7842BF5E2E5F7"
}
```

## Generate MAC using DUKPT CMAC
<a name="generate-mac-dukpt-cmac"></a>

In this example, we will generate a MAC using DUKPT (Derived Unique Key Per Transaction) with CMAC for card data authentication. The key must have KeyUsage set to `TR31_B0_BASE_DERIVATION_KEY` and KeyModesOfUse `DeriveKey` set to true. DUKPT keys derive a unique key for each transaction using a Base Derivation Key (BDK) and a Key Serial Number (KSN). 



**Example**  

```
$ aws payment-cryptography-data generate-mac --key-identifier arn:aws:payment-cryptography:us-east-2:111122223333:key/qnobl5lghrzunce6 --message-data "3b313038383439303031303733393431353d32343038323236303030373030303f33" --generation-attributes="DukptCmac={KeySerialNumber="932A6E954ABB32DD00000001",Direction=BIDIRECTIONAL}"
```

```
       
{
    "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/qnobl5lghrzunce6",
    "KeyCheckValue": "C1EB8F"
}
```

# Verify MAC
<a name="verify-mac"></a>

Verify MAC API is used to verify MAC (Message Authentication Code) for card-related data authentication. It must use the same encryption key used during generate MAC to re-produce MAC value for authentication. The MAC encryption key can either be created with AWS Payment Cryptography by calling [CreateKey](https://docs.aws.amazon.com/payment-cryptography/latest/APIReference/API_CreateKey.html) or imported by calling [ImportKey](https://docs.aws.amazon.com/payment-cryptography/latest/APIReference/API_ImportKey.html). The API supports DUKPT MAC, HMAC and EMV MAC encryption keys for this operation.

If the value is verified, then response parameter `MacDataVerificationSuccessful` will return `Http/200`, otherwise `Http/400` with a message indicating that `Mac verification failed`.

**Topics**
+ [Verify HMAC](#verify-mac-hmac)
+ [Verify MAC using DUKPT CMAC](#verify-mac-dukpt-cmac)

## Verify HMAC
<a name="verify-mac-hmac"></a>

In this example, we will verify a HMAC (Hash-Based Message Authentication Code) for card data authentication using HMAC algorithm `HMAC_SHA256` and HMAC encryption key. The key must have KeyUsage set to `TR31_M7_HMAC_KEY` and KeyModesOfUse `Verify` set to true. 

**Example**  

```
$ aws payment-cryptography-data verify-mac \ 
     --key-identifier arn:aws:payment-cryptography:us-east-2:111122223333:key/qnobl5lghrzunce6 \ 
     --message-data "3b343038383439303031303733393431353d32343038323236303030373030303f33" \ 
     --mac ED87F26E961C6D0DDB78DA5038AA2BDDEA0DCE03E5B5E96BDDD494F4A7AA470C \ 
     --verification-attributes Algorithm=HMAC_SHA256
```

```
       
{
    "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/qnobl5lghrzunce6",
    "KeyCheckValue": "2976E7"
}
```

## Verify MAC using DUKPT CMAC
<a name="verify-mac-dukpt-cmac"></a>

In this example, we will verify a MAC using DUKPT (Derived Unique Key Per Transaction) with CMAC for card data authentication. The key must have KeyUsage set to `TR31_B0_BASE_DERIVATION_KEY` and KeyModesOfUse `DeriveKey` set to true. DUKPT keys derive a unique key for each transaction using a Base Derivation Key (BDK) and a Key Serial Number (KSN). The value of DukptKeyVariant must match between sender and receiver. REQUEST will typically be used from terminal to backend, VERIFY from backend to terminal and BIDIRECTIONAL when a single key is used in both directions. 

**Example**  

```
$ aws payment-cryptography-data verify-mac \ 
     --key-identifier arn:aws:payment-cryptography:us-east-2:111122223333:key/tqv5yij6wtxx64pi \ 
     --message-data "3b343038383439303031303733393431353d32343038323236303030373030303f33" \ 
     --mac D8E804EE74BF1D909A2C01C0BDE8EF34 \ 
     --verification-attributes DukptCmac='{"KeySerialNumber":"932A6E954ABB32DD00000001","DukptKeyVariant":"BIDIRECTIONAL"}'
```

```
       
{
    "KeyArn": "arn:aws:payment-cryptography:us-east-2:111122223333:key/tqv5yij6wtxx64pi",
    "KeyCheckValue": "C1EB8F"
}
```