Skip to content

Commit 089d6b0

Browse files
authored
Merge pull request #124 from thephpleague/issue123
Issue123 - Support `signatureKey` for HMAC SHA-512 signing (SIM and DPM)
2 parents 23458a4 + 7871bd3 commit 089d6b0

7 files changed

+96
-9
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,20 @@ $data['paymentProfile']['customerPaymentProfileId'];
115115
//the rest of the CIM driver features as usual.
116116
```
117117

118+
## DPM and SIM Signatures
119+
120+
DPM and SIM used to sign their requests with the `transactionKey` using the mdh HMAC algorithm.
121+
From early 2019, this algorithm is being removed completely.
122+
Instead, the SHA-512 HMAC algorithm is used to sign the DPM and SIM requsts,
123+
and to validate the received notifications.
124+
125+
To start using the SHA-512 signing, set your `signatureKey` in the gateway:
126+
127+
```php
128+
$gateway->setSignatureKey('48D2C629E4A...{100}...E7CA3C4E6CD7223D');
129+
```
130+
131+
The `signatureKey` can be generated in the *API Credentials & Keys* section of your account setings.
118132

119133
## Support
120134

src/AIMGateway.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ public function getName()
2424
public function getDefaultParameters()
2525
{
2626
return array(
27-
'apiLoginId' => '',
28-
'transactionKey' => '',
27+
'apiLoginId' => null,
28+
'transactionKey' => null,
2929
'testMode' => false,
3030
'developerMode' => false,
31-
'hashSecret' => '',
31+
'hashSecret' => null,
3232
'liveEndpoint' => 'https://api2.authorize.net/xml/v1/request.api',
3333
'developerEndpoint' => 'https://apitest.authorize.net/xml/v1/request.api',
3434
);
@@ -54,6 +54,16 @@ public function setTransactionKey($value)
5454
return $this->setParameter('transactionKey', $value);
5555
}
5656

57+
public function getSignatureKey()
58+
{
59+
return $this->getParameter('signatureKey');
60+
}
61+
62+
public function setSignatureKey($value)
63+
{
64+
return $this->setParameter('signatureKey', $value);
65+
}
66+
5767
public function getDeveloperMode()
5868
{
5969
return $this->getParameter('developerMode');

src/Message/AIMAbstractRequest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,20 @@ public function setTransactionKey($value)
3636
return $this->setParameter('transactionKey', $value);
3737
}
3838

39+
// AIM does not use signatureKey, but it is included here just
40+
// to get the tests to run. Some structural refactoring will be
41+
// needed to work around this.
42+
43+
public function getSignatureKey()
44+
{
45+
return $this->getParameter('signatureKey');
46+
}
47+
48+
public function setSignatureKey($value)
49+
{
50+
return $this->setParameter('signatureKey', $value);
51+
}
52+
3953
public function getDeveloperMode()
4054
{
4155
return $this->getParameter('developerMode');

src/Message/SIMAbstractRequest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,16 @@ public function setTransactionKey($value)
3434
return $this->setParameter('transactionKey', $value);
3535
}
3636

37+
public function getSignatureKey()
38+
{
39+
return $this->getParameter('signatureKey');
40+
}
41+
42+
public function setSignatureKey($value)
43+
{
44+
return $this->setParameter('signatureKey', $value);
45+
}
46+
3747
public function getDeveloperMode()
3848
{
3949
return $this->getParameter('developerMode');

src/Message/SIMAuthorizeRequest.php

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,19 @@ public function getHash($data)
7878
).'^';
7979

8080
// If x_currency_code is specified, then it must follow the final trailing carat.
81+
8182
if ($this->getCurrency()) {
8283
$fingerprint .= $this->getCurrency();
8384
}
8485

85-
return hash_hmac('md5', $fingerprint, $this->getTransactionKey());
86+
// The md5 hash against the transactionKey is being removed 2019 and
87+
// replaced with an SHA-512 hash against the signatureKey.
88+
89+
if ($signatureKey = $this->getSignatureKey()) {
90+
return hash_hmac('sha512', $fingerprint, hex2bin($signatureKey));
91+
} else {
92+
return hash_hmac('md5', $fingerprint, $this->getTransactionKey());
93+
}
8694
}
8795

8896
public function sendData($data)

src/SIMGateway.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public function getDefaultParameters()
1616
{
1717
$parameters = parent::getDefaultParameters();
1818
$parameters = array_merge($parameters, array(
19-
'hashSecret' => '',
19+
'signatureKey' => null,
2020
'liveEndpoint' => 'https://secure2.authorize.net/gateway/transact.dll',
2121
'developerEndpoint' => 'https://test.authorize.net/gateway/transact.dll'
2222
));
@@ -33,14 +33,14 @@ public function setApiLoginId($value)
3333
return $this->setParameter('apiLoginId', $value);
3434
}
3535

36-
public function getTransactionKey()
36+
public function getSignatureKey()
3737
{
38-
return $this->getParameter('transactionKey');
38+
return $this->getParameter('signatureKey');
3939
}
4040

41-
public function setTransactionKey($value)
41+
public function setSignatureKey($value)
4242
{
43-
return $this->setParameter('transactionKey', $value);
43+
return $this->setParameter('signatureKey', $value);
4444
}
4545

4646
public function getDeveloperMode()

tests/Message/DPMAuthorizeRequestTest.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,37 @@ public function testGetData()
2929
$this->assertArrayNotHasKey('x_test_request', $data);
3030
}
3131

32+
/**
33+
* Issue #123 test the signature key.
34+
*/
35+
public function testSha512hash()
36+
{
37+
$signatureKey =
38+
'48D2C629E4A6D3E19AC47767C8B7EFEA4AE2004F8FA9C190F19D0238D871978B'
39+
. 'E35925A6AD9256FE623934C1099DFEFD6449D54744E5734CE7CA3C4E6CD7223D';
40+
41+
$this->request->setSignatureKey($signatureKey);
42+
43+
$data = $this->request->getData();
44+
$hash = $data['x_fp_hash'];
45+
46+
// Now check the hash.
47+
48+
$fingerprint = implode(
49+
'^',
50+
array(
51+
$this->request->getApiLoginId(),
52+
$data['x_fp_sequence'],
53+
$data['x_fp_timestamp'],
54+
$data['x_amount']
55+
)
56+
).'^';
57+
58+
$this->assertTrue(
59+
hash_equals(hash_hmac('sha512', $fingerprint, hex2bin($signatureKey)), $hash)
60+
);
61+
}
62+
3263
public function testGetDataTestMode()
3364
{
3465
$this->request->setTestMode(true);

0 commit comments

Comments
 (0)