bariew/whatsapp-crypto

PSR-7 stream decorators for WhatsApp-style encryption and decryption

Installs: 0

Dependents: 0

Suggesters: 0

Security: 0

Stars: 0

Watchers: 0

Forks: 0

Open Issues: 0

pkg:composer/bariew/whatsapp-crypto

0.1.1 2026-02-09 05:24 UTC

This package is auto-updated.

Last update: 2026-02-09 05:26:40 UTC


README

Latest Version License PHP Version

PSR-7 stream decorators for WhatsApp-style encryption and decryption of media files. This library implements the same encryption algorithm used by WhatsApp to encrypt images, videos, audio, and documents.

Features

  • Stream-based encryption/decryption: Uses PSR-7 stream decorators for memory-efficient processing
  • WhatsApp-compatible: Implements the exact same encryption algorithm as WhatsApp
  • Chunk-based MAC generation: Supports sidecar file generation for streaming scenarios
  • No external dependencies: Only requires PHP extensions that are commonly available
  • Well-tested: Comprehensive unit and integration tests with sample files

Installation

Install the package via Composer:

composer require bariew/whatsapp-crypto

Requirements

  • PHP 7.4 or higher
  • ext-openssl extension
  • ext-hash extension
  • psr/http-message (^1.0 or ^2.0)
  • guzzlehttp/psr7 (^2.0)

Quick Start

Encrypting a File

use GuzzleHttp\Psr7\Stream;
use bariew\WhatsAppCrypto\Factory\EncryptedStreamFactory;
use bariew\WhatsAppCrypto\Enum\MediaType;

// Your 32-byte mediaKey (raw binary)
$mediaKey = random_bytes(32);

// Open the source file and encrypted output
$sourceStream = fopen('/path/to/original/file.jpg', 'rb');
$encryptedStream = fopen('/path/to/encrypted/file.encrypted', 'wb');

$encryptedPsr7Stream = new Stream($encryptedStream);

// Create encrypted stream
$encryptor = new EncryptedStreamFactory();
$encrypted = $encryptor->create($encryptedPsr7Stream, $mediaKey, MediaType::IMAGE);

// Encrypt the file
$encrypted->readAndWrite(new Stream($sourceStream));

Decrypting a File

use GuzzleHttp\Psr7\Stream;
use bariew\WhatsAppCrypto\Factory\DecryptedStreamFactory;
use bariew\WhatsAppCrypto\Enum\MediaType;

// Your 32-byte mediaKey (raw binary)
$mediaKey = file_get_contents('/path/to/file.key');
$decryptedStream = fopen('/path/to/decrypted/file.jpg', 'wb');

// Create decrypted stream
$decryptor = new DecryptedStreamFactory();
$decrypted = $decryptor->createFromFile('/path/to/encrypted/file.encrypted', $mediaKey, MediaType::IMAGE);

// Decrypt the file
while (!$decrypted->eof()) {
    fwrite($decryptedStream, $decrypted->read(8192));
}
$decrypted->close();

Testing

Run the test suite:

composer test

The project includes integration tests with sample files for AUDIO, IMAGE, and VIDEO media types.

Sample Files

The samples/ directory contains test files:

  • *.original - Original unencrypted files
  • *.encrypted - Encrypted versions using WhatsApp-compatible encryption
  • *.key - The 32-byte mediaKeys used for encryption
  • VIDEO.sidecar - Example sidecar file for chunk-based verification

Security Considerations

  • MAC Truncation: WhatsApp uses the first 10 bytes of HMAC-SHA256. This is a deliberate design choice for compactness, though it reduces the theoretical security margin.
  • Timing-Safe Comparison: The library uses hash_equals() for MAC verification to prevent timing attacks.
  • Key Management: Keep your mediaKeys secure. Anyone with the mediaKey can decrypt the corresponding media.

License

This package is open-source software licensed under the MIT license.

Credits

This implementation is based on the WhatsApp encryption protocol as documented in various reverse-engineering efforts and the Signal protocol specifications.