Skip to content

Commit

Permalink
Merge pull request #124 from thephpleague/issue123
Browse files Browse the repository at this point in the history
Issue123 - Support `signatureKey` for HMAC SHA-512 signing (SIM and DPM)
  • Loading branch information
judgej authored Jan 20, 2019
2 parents 23458a4 + 7871bd3 commit 089d6b0
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 9 deletions.
14 changes: 14 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,20 @@ $data['paymentProfile']['customerPaymentProfileId'];
//the rest of the CIM driver features as usual.
```

## DPM and SIM Signatures

DPM and SIM used to sign their requests with the `transactionKey` using the mdh HMAC algorithm.
From early 2019, this algorithm is being removed completely.
Instead, the SHA-512 HMAC algorithm is used to sign the DPM and SIM requsts,
and to validate the received notifications.

To start using the SHA-512 signing, set your `signatureKey` in the gateway:

```php
$gateway->setSignatureKey('48D2C629E4A...{100}...E7CA3C4E6CD7223D');
```

The `signatureKey` can be generated in the *API Credentials & Keys* section of your account setings.

## Support

Expand Down
16 changes: 13 additions & 3 deletions src/AIMGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ public function getName()
public function getDefaultParameters()
{
return array(
'apiLoginId' => '',
'transactionKey' => '',
'apiLoginId' => null,
'transactionKey' => null,
'testMode' => false,
'developerMode' => false,
'hashSecret' => '',
'hashSecret' => null,
'liveEndpoint' => 'https://api2.authorize.net/xml/v1/request.api',
'developerEndpoint' => 'https://apitest.authorize.net/xml/v1/request.api',
);
Expand All @@ -54,6 +54,16 @@ public function setTransactionKey($value)
return $this->setParameter('transactionKey', $value);
}

public function getSignatureKey()
{
return $this->getParameter('signatureKey');
}

public function setSignatureKey($value)
{
return $this->setParameter('signatureKey', $value);
}

public function getDeveloperMode()
{
return $this->getParameter('developerMode');
Expand Down
14 changes: 14 additions & 0 deletions src/Message/AIMAbstractRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,20 @@ public function setTransactionKey($value)
return $this->setParameter('transactionKey', $value);
}

// AIM does not use signatureKey, but it is included here just
// to get the tests to run. Some structural refactoring will be
// needed to work around this.

public function getSignatureKey()
{
return $this->getParameter('signatureKey');
}

public function setSignatureKey($value)
{
return $this->setParameter('signatureKey', $value);
}

public function getDeveloperMode()
{
return $this->getParameter('developerMode');
Expand Down
10 changes: 10 additions & 0 deletions src/Message/SIMAbstractRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,16 @@ public function setTransactionKey($value)
return $this->setParameter('transactionKey', $value);
}

public function getSignatureKey()
{
return $this->getParameter('signatureKey');
}

public function setSignatureKey($value)
{
return $this->setParameter('signatureKey', $value);
}

public function getDeveloperMode()
{
return $this->getParameter('developerMode');
Expand Down
10 changes: 9 additions & 1 deletion src/Message/SIMAuthorizeRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,19 @@ public function getHash($data)
).'^';

// If x_currency_code is specified, then it must follow the final trailing carat.

if ($this->getCurrency()) {
$fingerprint .= $this->getCurrency();
}

return hash_hmac('md5', $fingerprint, $this->getTransactionKey());
// The md5 hash against the transactionKey is being removed 2019 and
// replaced with an SHA-512 hash against the signatureKey.

if ($signatureKey = $this->getSignatureKey()) {
return hash_hmac('sha512', $fingerprint, hex2bin($signatureKey));
} else {
return hash_hmac('md5', $fingerprint, $this->getTransactionKey());
}
}

public function sendData($data)
Expand Down
10 changes: 5 additions & 5 deletions src/SIMGateway.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public function getDefaultParameters()
{
$parameters = parent::getDefaultParameters();
$parameters = array_merge($parameters, array(
'hashSecret' => '',
'signatureKey' => null,
'liveEndpoint' => 'https://secure2.authorize.net/gateway/transact.dll',
'developerEndpoint' => 'https://test.authorize.net/gateway/transact.dll'
));
Expand All @@ -33,14 +33,14 @@ public function setApiLoginId($value)
return $this->setParameter('apiLoginId', $value);
}

public function getTransactionKey()
public function getSignatureKey()
{
return $this->getParameter('transactionKey');
return $this->getParameter('signatureKey');
}

public function setTransactionKey($value)
public function setSignatureKey($value)
{
return $this->setParameter('transactionKey', $value);
return $this->setParameter('signatureKey', $value);
}

public function getDeveloperMode()
Expand Down
31 changes: 31 additions & 0 deletions tests/Message/DPMAuthorizeRequestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,37 @@ public function testGetData()
$this->assertArrayNotHasKey('x_test_request', $data);
}

/**
* Issue #123 test the signature key.
*/
public function testSha512hash()
{
$signatureKey =
'48D2C629E4A6D3E19AC47767C8B7EFEA4AE2004F8FA9C190F19D0238D871978B'
. 'E35925A6AD9256FE623934C1099DFEFD6449D54744E5734CE7CA3C4E6CD7223D';

$this->request->setSignatureKey($signatureKey);

$data = $this->request->getData();
$hash = $data['x_fp_hash'];

// Now check the hash.

$fingerprint = implode(
'^',
array(
$this->request->getApiLoginId(),
$data['x_fp_sequence'],
$data['x_fp_timestamp'],
$data['x_amount']
)
).'^';

$this->assertTrue(
hash_equals(hash_hmac('sha512', $fingerprint, hex2bin($signatureKey)), $hash)
);
}

public function testGetDataTestMode()
{
$this->request->setTestMode(true);
Expand Down

0 comments on commit 089d6b0

Please sign in to comment.