toArray(); // 2. Remove existing signatures if any unset($data['digestSignatures']); // 3. Canonicalize (RFC 8785 - simple version: sort keys, remove nulls, no spaces) $canonicalData = $this->canonicalizeArray($data); $jsonToSign = json_encode($canonicalData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); // 4. Sign $signature = $signer->sign($jsonToSign); // 5. Attach signature to the original object if ($this->digestSignatures === null) { $this->digestSignatures = new DataCollection(DigestSignatureData::class, []); } $current = array_values($this->digestSignatures->toCollection()->all()); $current[] = new DigestSignatureData($signature, 'RSA'); $this->digestSignatures = new DataCollection(DigestSignatureData::class, $current); return $this; } private function canonicalizeArray(array $array): array { // Remove nulls and empty strings $array = array_filter($array, fn ($v) => $v !== null); // Sort keys lexically ksort($array); foreach ($array as $key => $value) { if (is_array($value)) { $array[$key] = $this->canonicalizeArray($value); } } return $array; } }