Post

Replies

Boosts

Views

Activity

Reply to Decryption of Business Chat Attachment
Hello all! I also wanted to provide a solution for people who use PHP. I hope this helps someone who might run into problems. Here an example how you can access the encoded attachment data by calling the /preDownload endpoint, decode the attachment payload and process it. // get the request $raw_input = file_get_contents('php://input'); $data = json_decode(gzdecode($raw_input), true); // check if there are attachments if(!isset($data['attachments']) || empty($data['attachments'])) { return false; } // jwt for Authorization for the preDownload $jwt_payload = [ 'iss' => <MSP_ID>, 'iat' => time() ]; // iterate through all attachments foreach($this->data['attachments'] as $k => $attachment) { //get hex encoded signature and convert to base64 $hex_encoded_signature = $attachment['signature']; $base64_encoded_signature = base64_encode(pack('H*', $hex_encoded_signature)); $predownload_headers = [ "Authorization" => 'Bearer '.utf8_decode(jwt_encode($jwt_payload, base64_decode(<MSP_SECRET>))), "source-id" => <BUSINESS_CHAT_ID>, "MMCS-Url" => $attachment['url'], "MMCS-Signature" => $base64_encoded_signature, "MMCS-Owner" => $attachment['owner'] ]; // get the download url of the attachment $pre_download_data = json_decode(perform_pre_download($predownload_headers), true); $download_url = $pre_download_data['download-url']; // Now that we have the url to download the encrypted payload we have to decode the payload data // get the encoded file and the key to decode it $binary = @file_get_contents($download_url); $decrypted_key = $attachment['key']; // decode via openssl $binary = openssl_decrypt( base64_encode($binary), "aes-256-ctr", pack("H*", substr($decrypted_key, 2)), OPENSSL_ZERO_PADDING, pack("H*", "00000000000000000000000000000000") ); // from here on you can access the decoded image and process it in your code // you can add specific checks to validate the attachments like: $image = @getimagesizefromstring($binary); // check for valid mime types if (empty($image['mime']) && !in_array($image['mime'], ['image/jpeg','image/png', 'image/gif'])) {         continue;   // skip this attachment } // make sure to store the image on your server since the 'download-url' from the perform_pre_download function will not // be accessable after some time file_put_contents(<PATH_TO_THE_FILE>, $binary); } // function to access the url where you can get the encoded attachment data function perform_pre_download($headers) { //prepare headers $request_header = []; //parse headers foreach($headers as $k => $v) { $request_header[] = $k.': '.$v; } $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, <URL_TO_PREDOWNLOAD_ENDPOINT>); curl_setopt($ch, CURLOPT_HTTPHEADER, $request_header); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 5); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // get response body $return = curl_exec($ch); // end curl request curl_close($ch); return $return; } // create jwt token function jwt_encode(array $payload, string $secret):string { $header = encode_base64_url_safe(json_encode(['typ' => 'JWT', 'alg' => 'HS256'])); $payload = encode_base64_url_safe(json_encode($payload));     $signature = encode_base64_url_safe(hash_hmac('sha256', $header.'.'.$payload, $secret, true));     return $header.'.'.$payload.'.'.$signature; }
Aug ’21