|
@@ -280,22 +280,65 @@ class PayPlus
|
|
|
throw new Exception('PayPlus public key is empty.');
|
|
throw new Exception('PayPlus public key is empty.');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- if (!class_exists('\phpseclib\Crypt\RSA')) {
|
|
|
|
|
- throw new Exception('phpseclib is required for PayPlus RSA OAEP SHA-512.');
|
|
|
|
|
|
|
+ $details = $this->getPublicKeyDetails($publicKey);
|
|
|
|
|
+ $encoded = $this->oaepSha512Encode((string) $value, strlen($details['n']));
|
|
|
|
|
+ $encrypted = '';
|
|
|
|
|
+ $success = openssl_public_encrypt(
|
|
|
|
|
+ $encoded,
|
|
|
|
|
+ $encrypted,
|
|
|
|
|
+ $this->normalizePublicKey($publicKey),
|
|
|
|
|
+ OPENSSL_NO_PADDING
|
|
|
|
|
+ );
|
|
|
|
|
+ if (!$success) {
|
|
|
|
|
+ throw new Exception('PayPlus RSA encrypt failed.');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- $rsa = new \phpseclib\Crypt\RSA();
|
|
|
|
|
- $rsa->setEncryptionMode(\phpseclib\Crypt\RSA::ENCRYPTION_OAEP);
|
|
|
|
|
- $rsa->setHash('sha512');
|
|
|
|
|
- $rsa->setMGFHash('sha512');
|
|
|
|
|
- $rsa->loadKey($this->normalizePublicKey($publicKey));
|
|
|
|
|
|
|
+ return base64_encode($encrypted);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- $encrypted = $rsa->encrypt($value);
|
|
|
|
|
- if ($encrypted === false) {
|
|
|
|
|
- throw new Exception('PayPlus RSA encrypt failed.');
|
|
|
|
|
|
|
+ protected function getPublicKeyDetails($publicKey)
|
|
|
|
|
+ {
|
|
|
|
|
+ $resource = openssl_pkey_get_public($this->normalizePublicKey($publicKey));
|
|
|
|
|
+ if ($resource === false) {
|
|
|
|
|
+ throw new Exception('PayPlus public key is invalid.');
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return base64_encode($encrypted);
|
|
|
|
|
|
|
+ $details = openssl_pkey_get_details($resource);
|
|
|
|
|
+ if (!isset($details['rsa']['n'], $details['rsa']['e'])) {
|
|
|
|
|
+ throw new Exception('PayPlus RSA public key details are invalid.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return $details['rsa'];
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected function oaepSha512Encode($message, $keyLength)
|
|
|
|
|
+ {
|
|
|
|
|
+ $hashLength = 64;
|
|
|
|
|
+ $messageLength = strlen($message);
|
|
|
|
|
+ if ($messageLength > $keyLength - 2 * $hashLength - 2) {
|
|
|
|
|
+ throw new Exception('PayPlus RSA message is too long.');
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ $labelHash = hash('sha512', '', true);
|
|
|
|
|
+ $padding = str_repeat("\x00", $keyLength - $messageLength - 2 * $hashLength - 2);
|
|
|
|
|
+ $dataBlock = $labelHash . $padding . "\x01" . $message;
|
|
|
|
|
+ $seed = random_bytes($hashLength);
|
|
|
|
|
+ $maskedDataBlock = $dataBlock ^ $this->mgf1Sha512($seed, $keyLength - $hashLength - 1);
|
|
|
|
|
+ $maskedSeed = $seed ^ $this->mgf1Sha512($maskedDataBlock, $hashLength);
|
|
|
|
|
+
|
|
|
|
|
+ return "\x00" . $maskedSeed . $maskedDataBlock;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ protected function mgf1Sha512($seed, $length)
|
|
|
|
|
+ {
|
|
|
|
|
+ $mask = '';
|
|
|
|
|
+ $counter = 0;
|
|
|
|
|
+ while (strlen($mask) < $length) {
|
|
|
|
|
+ $mask .= hash('sha512', $seed . pack('N', $counter), true);
|
|
|
|
|
+ $counter++;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return substr($mask, 0, $length);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
protected function buildPayinHeaders()
|
|
protected function buildPayinHeaders()
|