PHP Code:
<?php
class Steganography
{
var $m_errMsg;
var $m_dataCarrier;
var $m_data;
var $m_key;
var $m_outFile;
function __construct()
{
$this->m_errMsg = "";
$this->m_dataCarrier = "";
$this->m_data = "";
$this->m_key = "ExiledHeroBmpCrypt";
$this->m_outFile = "";
}
function Encrypt( $bmpFile, $indata, $key, $outFile, $level = 1)
{
if ( !file_exists( $bmpFile ) )
{
$this->m_errMsg = "The bitmap file '" . $bmpFile . "' was not found!";
return false;
}
if ( $indata == "" )
{
$this->m_errMsg = "No data to encrypt!";
return false;
}
if ( $outFile == "" )
{
$this->m_errMsg = "The output file was not specified!";
return false;
}
$this->m_dataCarrier = $bmpFile;
$this->m_data = $indata;
if ( $key != "" ) $this->m_key = $key;
$this->m_outFile = $outFile;
if ( $level == 1 )
return $this->_encrypt_1();
else if ( $level == 2 )
return $this->_encrypt_2();
else if ( $level == 3 )
return $this->_encrypt_3();
else if ( $level == 4 )
return $this->_encrypt_4();
else
{
$this->m_errMsg = "The encryption level is out of range!";
return false;
}
}
function Decrypt( $bmpFile, $key, $outFile = "" )
{
if ( !file_exists( $bmpFile ) )
{
$this->m_errMsg = "The bitmap file '" . $bmpFile . "' was not found!";
return false;
}
if ( $key != "" ) $this->m_key = $key;
$this->m_outFile = $outFile;
$this->m_dataCarrier = $bmpFile;
$this->m_data = file_get_contents( $this->m_dataCarrier );
if ( !$this->_get_encryption_info( $level, $cryptKey, $offset, $datSize ) )
return false;
$nbytes = ( $level == 1 ) ? 8 : ( ( $level == 2 ) ? 4 : ( ( $level == 3 ) ? 3 : 2 ) );
if ( $offset + $datSize * $nbytes > strlen( $this->m_data ) )
{
$this->m_errMsg = "The bitmap file '" . $this->m_dataCarrier . "' contains no encrypted data!" . $level . ", $nbytes";
return false;
}
$data = "";
for ( $i = 0; $i < $datSize; $i++ )
$data = chr( 0 );
for ( $i = $offset, $j = 0; $i < $offset + $datSize * $nbytes; $i += $nbytes, $j++ )
{
if ( $level == 1 )
{
for ( $k = 0, $n = 7; $k < 8; $k++, $n-- )
$data[ $j ] = chr( ord( $data[ $j ] ) | ( ( ord( $this->m_data[ $i + $k ] ) & 1 ) << $n ) );
}
else if ( $level == 2 )
{
for ( $k = 0, $n = 6; $k < 4; $k++, $n -= 2 )
$data[ $j ] = chr( ord( $data[ $j ] ) | ( ( ord( $this->m_data[ $i + $k ] ) & 3 ) << $n ) );
}
else if ( $level == 3 )
{
for ( $k = 0; $k < 3; $k++ )
{
if ( $k == 0 )
$data[ $j ] = chr( ord( $data[ $j ] ) | ( ( ord( $this->m_data[ $i ] ) & 7 ) << 5 ) );
else if ( $k == 1 )
$data[ $j ] = chr( ord( $data[ $j ] ) | ( ( ord( $this->m_data[ $i + 1 ] ) & 7 ) << 2 ) );
else
$data[ $j ] = chr( ord( $data[ $j ] ) | ( ord( $this->m_data[ $i + 2 ] ) & 3 ) );
}
}
else if ( $level == 4 )
{
for ( $k = 0; $k < 2; $k++ )
{
if ( $k == 0 )
$data[ $j ] = chr( ord( $data[ $j ] ) | ( ( ord( $this->m_data[ $i ] ) & 15 ) << 4 ) );
else
$data[ $j ] = chr( ord( $data[ $j ] ) | ( ( ord( $this->m_data[ $i + 1 ] ) & 15 ) );
}
}
}
for ( $i = 0, $j = 0; $i < $datSize; $i++, $j = ( $j + 1 ) % 32 )
$data[ $i ] = chr( ord( $data[ $i ] ) ^ ord( $cryptKey[ $j ] ) );
if ( $this->m_outFile != "" )
(
$fp = fopen( $this->m_outFile, "wb" );
fwrite( $fp, $data, $datSize );
fclose( $fp );
return true;
}
return $data;
}
function GetErrorMessage()
{
return "ERROR: " . $this->m_errMsg;
}
function _encrypt_1()
{
$bmpSize = filesize( $this->m_dataCarrier );
$datSize = strlen( $this->m_data );
$totalSize = ( 12 + $datSize ) * 8;
if ( ( $bmpSize - 55 ) < $totalSize )
{
$this->m_errMsg = "The bitmap file '" . $bmpFile . "' is too small to carry the input data!";
return false;
}
$cryptKey = md5( $this->m_key );
$cryptData = sprintf( "SCC1%08x", $datSize );
$bmpBuffer = file_get_contents( $this->m_dataCarrier );
for ( $i = 0, $j = 0; $i < $datSize; $i++, $j = ( $j + 1 ) % 32 )
$cryptData . = chr( ord( $this->m_data[ $i ] ) ^ ord( $cryptKey[ $j ] ) );
for ( $i = 0, $j = 55; $i < strlen( $cryptData ); $i++, $j += 8 )
{
$temp = sprintf( "%08s", decbin( ord( $cryptData[ $i ] ) ) );
for ( $k = 0; $k < 8; $k++ )
{
$bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) & 254 );
if ( $temp[ $k ] == '1' ) $bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) + 1 );
}
}
$fp = fopen($ this->m_outFile, "wb" );
fwrite( $fp, $bmpBuffer );
fclose( $fp );
return true;
}
function _encrypt_2()
{
$bmpSize = filesize( $this->m_dataCarrier );
$datSize = strlen( $this->m_data );
$totalSize = ( 12 + $datSize ) * 4;
if ( ( $bmpSize - 55 ) < $totalSize )
{
$this->m_errMsg = "The bitmap file '" . $this->m_dataCarrier . "' is too small to carry the input data!";
return false;
}
$cryptKey = md5( md5( $this->m_key ) );
$cryptData = sprintf( "SCC2%08x", $datSize );
$bmpBuffer = file_get_contents( $this->m_dataCarrier );
for ( $i = 0, $j = 0; $i < $datSize; $i++, $j = ( $j + 1 ) % 32 )
$cryptData .= chr( ord( $this->m_data[ $i ] ) ^ ord( $cryptKey[ $j ] ) );
for ( $i = 0, $j = 55; $i < strlen( $cryptData ); $i++, $j += 4 )
{
$temp = sprintf( "%08s", decbin( ord( $cryptData[ $i ] ) ) );
for ( $k = 0; $k < 4; $k++ )
{
$bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) & 252 );
$n = ( $temp[ $k * 2 ] == '1' ) ? 2 : 0;
$n += ( $temp[ $k * 2 + 1 ] == '1' ) ? 1 : 0;
if ( $n != 0 ) $bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) + $n );
}
}
$fp = fopen( $this->m_outFile, "wb" );
fwrite( $fp, $bmpBuffer );
fclose( $fp );
return true;
}
function _encrypt_3()
{
$bmpSize = filesize( $this->m_dataCarrier );
$datSize = strlen( $this->m_data );
$totalSize = ( 12 + $datSize ) * 3;
if ( ( $bmpSize - 55 ) < $totalSize )
{
$this->m_errMsg = "The bitmap file '" . $this->m_dataCarrier . "' is too small to carry the input data!";
return false;
}
$cryptKey = md5( md5( md5( $this->m_key ) ) );
$cryptData = sprintf( "SCC3%08x", $datSize );
$bmpBuffer = file_get_contents( $this->m_dataCarrier );
for ($i = 0, $j = 0; $i < $datSize; $i++, $j = ( $j + 1 ) % 32 )
$cryptData .= chr( ord( $this->m_data[ $i ] ) ^ ord( $cryptKey[ $j ] ) );
for ( $i = 0, $j = 55; $i < strlen( $cryptData ); $i++, $j += 3 )
{
$temp = sprintf( "%08s", decbin( ord( $cryptData[ $i ] ) ) );
for ( $k = 0; $k < 3; $k++ )
{
if ( $k != 2 )
{
$bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) & 248 );
$n = ( $temp[ $k * 3 ] == '1' ) ? 4 : 0;
$n += ( $temp[ $k * 3 + 1 ] == '1' ) ? 2 : 0;
$n += ( $temp[ $k * 3 + 2 ] == '1') ? 1 : 0;
if ( $n != 0 ) $bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) + $n );
}
else
{
$bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) & 252 );
$n = ( $temp[ $k * 3 ] == '1' ) ? 2 : 0;
$n += ( $temp[ $k * 3 + 1 ] == '1' ) ? 1 : 0;
if ( $n != 0 ) $bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) + $n );
}
}
}
$fp = fopen( $this->m_outFile, "wb" );
fwrite( $fp, $bmpBuffer );
fclose( $fp );
return true;
}
function _encrypt_4()
{
$bmpSize = filesize( $this->m_dataCarrier );
$datSize = strlen( $this->m_data );
$totalSize = ( 12 + $datSize ) * 2;
if ( ( $bmpSize - 55 ) < $totalSize )
{
$this->m_errMsg = "The bitmap file '" . $this->m_dataCarrier . "' is too small to carry the input data!";
return false;
}
$cryptKey = md5( md5( md5( md5( $this->m_key ) ) ) );
$cryptData = sprintf( "SCC4%08x", $datSize );
$bmpBuffer = file_get_contents( $this->m_dataCarrier );
for ( $i = 0, $j = 0; $i < $datSize; $i++, $j = ( $j + 1 ) % 32 )
$cryptData .= chr( ord( $this->m_data[ $i ] ) ^ ord( $cryptKey[ $j ] ) );
for ( $i = 0, $j = 55; $i < strlen( $cryptData ); $i++, $j += 2 )
{
$temp = sprintf( "%08s", decbin( ord( $cryptData[ $i ] ) ) );
for ( $k = 0; $k < 2; $k++ )
{
$bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) & 240 );
$n = ( $temp[ $k * 4 ] == '1' ) ? 8 : 0;
$n += ( $temp[ $k * 4 + 1] == '1' ) ? 4 : 0;
$n += ( $temp[ $k * 4 + 2 ] == '1' ) ? 2 : 0;
$n += ( $temp[ $k * 4 + 3] == '1' ) ? 1 : 0;
if ( $n != 0 ) $bmpBuffer[ $k + $j ] = chr( ord( $bmpBuffer[ $k + $j ] ) + $n );
}
}
$fp = fopen( $this->m_outFile, "wb" );
fwrite( $fp, $bmpBuffer );
fclose( $fp );
return true;
}
function _get_encryption_info( &$level, &$cryptKey, &$offset, &$datSize )
{
$cryptKey = md5( $this->m_key );
$cryptHeader = "";
for ( $i = 0; $i < 12; $i++ )
$cryptHeader = chr( 0 );
for ( $i = 55, $j = 7, $k = 0; $i < 151; $i++ )
{
$cryptHeader[ $k ] = chr( ord( $cryptHeader[ $k ] ) | ( ( ord( $this->m_data[ $i ] ) & 1 ) << $j ) );
$j--;
if ( $j < 0 )
{
$j = 7;
$k++;
}
}
if ( !strcmp( substr( $cryptHeader, 0, 4 ), "SCC1" ) )
{
sscanf( substr( $cryptHeader, 4, 8 ), "%x", $datSize );
$level = 1;
$offset = 151;
return true;
}
$cryptKey = md5( $cryptKey );
$cryptHeader = "";
for ( $i = 0; $i < 12; $i++ )
$cryptHeader = chr( 0 );
for ( $i = 55, $j = 6, $k = 0; $i < 103; $i++ )
{
$cryptHeader[ $k ] = chr( ord( $cryptHeader[ $k ] ) | ( ( ord( $this->m_data[ $i ] ) & 3 ) << $j ) );
$j -= 2;
if ( $j < 0 )
{
$j = 6;
$k++;
}
}
if ( !strcmp( substr( $cryptHeader, 0, 4 ), "SCC2" ) )
{
sscanf( substr( $cryptHeader, 4, 8 ), "%x", $datSize );
$level = 2;
$offset = 103;
return true;
}
$cryptKey = md5( $cryptKey );
$cryptHeader = "";
for ( $i = 0; $i < 12; $i++ )
$cryptHeader = chr( 0 );
for ( $i = 55, $j = 0; $i < 91; $i += 3, $j++ )
{
for ( $k = 0; $k < 3; $k++ )
{
if ( $k == 0 )
$cryptHeader[ $j ] = chr( ord( $cryptHeader[ $j ] ) | ( ( ord( $this->m_data[ $i ] ) & 7 ) << 5 ) );
else if ( $k == 1 )
$cryptHeader[ $j ] = chr( ord( $cryptHeader[ $j ] ) | ( ( ord( $this->m_data[ $i + 1 ] ) & 7 ) << 2 ) );
else
$cryptHeader[ $j ] = chr( ord( $cryptHeader[ $j ] ) | ( ord( $this->m_data[ $i + 2 ] ) & 3 ) );
}
}
if ( !strcmp( substr( $cryptHeader, 0, 4 ), "SCC3" ) )
{
sscanf( substr( $cryptHeader, 4, 8 ), "%x", $datSize );
$level = 3;
$offset = 91;
return true;
}
$cryptKey = md5( $cryptKey );
$cryptHeader = "";
for ( $i = 0; $i < 12; $i++ )
$cryptHeader = chr( 0 );
for ( $i = 55, $j = 0; $i < 79; $i += 2, $j++ )
{
for ( $k = 0; $k < 2; $k++ )
{
if ( $k == 0 )
$cryptHeader[ $j ] = chr( ord($cryptHeader[ $j ] ) | ( ( ord( $this->m_data[ $i ] ) & 15 ) << 4 ) );
else
$cryptHeader[ $j ] = chr( ord( $cryptHeader[ $j ] ) | ( ord( $this->m_data[ $i + 1 ] ) & 15 ) );
}
}
if ( !strcmp( substr( $cryptHeader, 0, 4 ), "SCC4" ) )
{
sscanf( substr( $cryptHeader, 4, 8 ), "%x", $datSize );
$level = 4;
$offset = 79;
return true;
}
$this->m_errMsg = "The bitmap file '" . $this->m_dataCarrier . "' contains no encrypted data!" . $cryptHeader;
return false;
}
}
/* EOF */
Command Line example: