Skip to content

Commit

Permalink
Optim the wx biz msg cryptor (#2883)
Browse files Browse the repository at this point in the history
* replace magic number with details of the wx specification

* less code comments, ref de5d462
  • Loading branch information
TheNorthMemory authored Feb 8, 2025
1 parent ba3975e commit 5d29981
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 12 deletions.
22 changes: 15 additions & 7 deletions src/Kernel/Encryptor.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
use function trim;
use function unpack;

/**
* @link https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Message_encryption_and_decryption_instructions.html
* @link https://developer.work.weixin.qq.com/document/path/96211
*/
class Encryptor
{
public const ERROR_INVALID_SIGNATURE = -40001; // Signature verification failed
Expand All @@ -55,14 +59,15 @@ class Encryptor

public const ILLEGAL_BUFFER = -41003; // Illegal buffer

/** AES block size in bytes */
private const BLOCK_SIZE = 16;

protected string $appId;

protected string $token;

protected string $aesKey;

protected int $blockSize = 32;

protected ?string $receiveId = null;

public function __construct(string $appId, string $token, string $aesKey, ?string $receiveId = null)
Expand Down Expand Up @@ -110,14 +115,17 @@ public function encryptAsXml(string $plaintext, ?string $nonce = null, int|strin
public function encryptAsArray(string $plaintext, ?string $nonce = null, int|string|null $timestamp = null): array
{
try {
$plaintext = Pkcs7::padding(random_bytes(16).pack('N', strlen($plaintext)).$plaintext.$this->appId, 32);
$plaintext = Pkcs7::padding(
random_bytes(self::BLOCK_SIZE).pack('N', strlen($plaintext)).$plaintext.$this->appId,
blockSize: strlen($this->aesKey)
);
$ciphertext = base64_encode(
openssl_encrypt(
$plaintext,
'aes-256-cbc',
$this->aesKey,
OPENSSL_NO_PADDING,
substr($this->aesKey, 0, 16)
iv: substr($this->aesKey, 0, self::BLOCK_SIZE)
) ?: ''
);
} catch (Throwable $e) {
Expand Down Expand Up @@ -159,11 +167,11 @@ public function decrypt(string $ciphertext, string $msgSignature, string $nonce,
'aes-256-cbc',
$this->aesKey,
OPENSSL_NO_PADDING,
substr($this->aesKey, 0, 16)
iv: substr($this->aesKey, 0, self::BLOCK_SIZE)
) ?: '',
32
blockSize: strlen($this->aesKey)
);
$plaintext = substr($plaintext, 16);
$plaintext = substr($plaintext, self::BLOCK_SIZE);
$contentLength = (unpack('N', substr($plaintext, 0, 4)) ?: [])[1];

if ($this->receiveId && trim(substr($plaintext, $contentLength + 4)) !== $this->receiveId) {
Expand Down
4 changes: 2 additions & 2 deletions src/Kernel/Form/Form.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static function create(array $fields): Form
}

/**
* @return array<string,mixed>
* @return array{headers:array<string,string|string[]>,body:string}
*/
#[ArrayShape(['headers' => 'array', 'body' => 'string'])]
public function toArray(): array
Expand All @@ -33,7 +33,7 @@ public function toArray(): array
}

/**
* @return array<string,mixed>
* @return array{headers:array<string,string|string[]>,body:string}
*/
#[ArrayShape(['headers' => 'array', 'body' => 'string'])]
public function toOptions(): array
Expand Down
4 changes: 2 additions & 2 deletions src/Kernel/Support/Pkcs7.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ class Pkcs7
*/
public static function padding(string $contents, int $blockSize): string
{
if ($blockSize > 256) {
throw new InvalidArgumentException('$blockSize may not be more than 256');
if ($blockSize > 32) {
throw new InvalidArgumentException('$blockSize may not be more than 32 bytes(256 bits)');
}
$padding = $blockSize - (strlen($contents) % $blockSize);
$pattern = chr($padding);
Expand Down
1 change: 0 additions & 1 deletion src/Pay/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,6 @@ public function uploadMedia(string $uri, string $pathOrContents, ?array $meta =
'meta' => new DataPart($meta, null, 'application/json'),
]);

/** @var array{headers:array,body:string} $options */
$options = $signatureOptions = $form->toOptions();

$signatureOptions['body'] = $meta;
Expand Down

0 comments on commit 5d29981

Please sign in to comment.