روشن فکری بنیان ماست !

ما هرگز نمی گذاریم حوصله شما سربرود !

اللَّهُ نُورُ السَّمَاوَاتِ وَالْأَرْضِ مَثَلُ نُورِهِ کَمِشْکَاةٍ فِیهَا مِصْبَاحٌ الْمِصْبَاحُ فِی زُجَاجَةٍ الزُّجَاجَةُ کَأَنَّهَا کَوْکَبٌ دُرِّیٌّ یُوقَدُ مِن شَجَرَةٍ مُّبَارَکَةٍ زَیْتُونِةٍ لَّا شَرْقِیَّةٍ وَلَا غَرْبِیَّةٍ یَکَادُ زَیْتُهَا یُضِیءُ وَلَوْ لَمْ تَمْسَسْهُ نَارٌ نُّورٌ عَلَی نُورٍ یَهْدِی اللَّهُ لِنُورِهِ مَن یَشَاءُ وَیَضْرِبُ اللَّهُ الْأَمْثَالَ لِلنَّاسِ وَاللَّهُ بِکُلِّ شَیْءٍ عَلِیمٌ ( برخی از خواص آینه ۳۵ سوره نور از کتاب قرآن کریم )
هرگونه کپی برداری از فایل های اختصاصی پیگرد قانونی دارد لذا در صورت کپی مطالب لینک دریافت آن ها را تغییر ندهید .
روشن فکری بنیان ماست !

به نام او که یادش ترنم عارفانه زندگیست . سلام من سید امیرحسین طــاووســی هستم طــراح و برنامه نویس وب . فـعالیتم را در زمینه کــامپـیوتـر قبل از سـال اول دبـسـتـان شـروع کــردم و تا دوره راهنمایی اطلاعات کاملی از این تکنولوژی بدست آوردم . از ان دوره تا کنون در زمینه های مختلف فعالیت می کنم که مهـم ترین آن برنامه نویسی وب است یکی از عواملی که باعث شد تا به این سمت بیام کـدباز بودن زبان های وب هستش و روز به روز به دانستنیهایم در این زمینه می افزایم. شاد و سرزنده باشید , امیر

جستجو در وبلاگ
آخرین نظرات

درصد پیشرفت پروژه ها

Projects Progress
اسکریپت اشتراک ویدیو + منتظر بزرگترین سوپرایز وبلاگ من در فروردین ۹۵ باشید۷۹ درصد

دریافت جزیات اسکریپت اشتراک ویدیو

معرفی کلاس امنیت تصاویر

شنبه, ۲۹ شهریور ۱۳۹۳، ۰۶:۱۸ ب.ظ

شاید شما هم از آن دسته افرادی هستید که نگران کپی شدن برخی تصاویر اختصاصی وبسایت خود هستید و راه های مختلفی را بررسی کردید اما به نتیجه دلخواه خود نرسیدید . خوب تا قبل امروز بهترین کار استفاده از واترمارک با کمی htaccess رو بهتون پیشنهاد می کردم ولی امروز قصد دارم روش جالب و جدیدی رو معرفی کنم که تا حد زیادی نسبت به راه های قبلی بهتر عمل می کند هر چند هر روش جدید مشکلات خاص خودشو دارد . خوب تا حالا به این فکر کرده بودید چی می شود اگر سورس اصلی تصویر واتر مارک داشته باشد ولی نسخه نمایش داده شده نه ؟ مگه میشه با کلاس های برنامه نویسی در این حد تصویر ساخته شده را ویرایش کرد و واترمارک رو حذف ؟ قطعا پاسخ شما هم خیر هست اما تغییرات کوچک امکان پذیر هست پس به معرفی این کلاس خارق العاده می پردازیم .

خوب یه نگاهی به تابع زیر میندازیم :

/**
 * imagesafe. Protect your images
 * Copyright w-labs | Patrick Wied
 * http://w-labs.at
 * http://www.patrick-wied.at
 */

/* add your images here. you can also use a database and fetch it from there. */
$images = array(
	"1" => "logo.png",
	"2" => "testimage.png",
	"3" => "testimage.png"
);

$currentImage = "";

if (isset($_GET['id']) && array_key_exists($_GET['id'], $images)) {
	$currentImage = $images[$_GET['id']];
} else {
	die();
}

function getIP() {
  $ip;
  if (getenv("HTTP_CLIENT_IP"))
  $ip = getenv("HTTP_CLIENT_IP");
  else if(getenv("HTTP_X_FORWARDED_FOR"))
  $ip = getenv("HTTP_X_FORWARDED_FOR");
  else if(getenv("REMOTE_ADDR"))
  $ip = getenv("REMOTE_ADDR");
  else
  $ip = "UNKNOWN";
  return $ip;
}

/* image encryption functionality. */
function imgEncrypt($imgUrl, $options=null) {
	$mode = "png";

	if(strpos($imgUrl, ".jpg") > 0 || strpos($imgUrl, ".jpeg") > 0) {
		$mode = "jpg";
	} else if (strpos($imgUrl, ".gif")) {
		$mode = "gif";
	}

	switch($mode) {
		case "png":
			$img = imagecreatefrompng($imgUrl);
			imagealphablending($img, true);
			imagesavealpha($img, true);
		break;
		case "jpg":
			$img = imagecreatefromjpeg($imgUrl);
		break;
		case "gif":
			$img = imagecreatefromgif($imgUrl);
		break;
	}

	$width = imagesx($img);
	$height = imagesy($img);
	$pixels = $width * $height;
	$swapFactor = isset($options['swapFactor']) ? $options['swapFactor'] : 4;
	$jumpFactor = isset($options['jumpFactor']) ? $options['jumpFactor'] : 5;

	$stamp = "++++++".getIP()."++++++";
	$len = strlen($stamp);
	for($i=0; $i<$len; $i+=3) {
		$red = ord($i < $len?$stamp[$i]:'-');
		$green = ord($i+1 < $len?$stamp[$i+1]:'-');
		$blue = ord($i+2 < $len?$stamp[$i+2]:'-');
		$color = imagecolorallocate($img, $red, $green, $blue);
		imagesetpixel($img, $i/3, 0, $color);
	}

	for($i=1; $i < $pixels; $i+=$jumpFactor) {
		$x = $i % $width;
		$y = floor($i / $width);
		$pixel1 = imagecolorat($img, $x, $y);
		$x2 = ($i + $swapFactor) % $width;
		$y2 = floor(($i + $swapFactor) / $width);
		if ( $y2 > $height-1) {
			$y2 = $height-1;
		}
		$pixel2 = imagecolorat($img, $x2, $y2);
		

		imagesetpixel($img, $x, $y, $pixel2);
		imagesetpixel($img, $x2, $y2, $pixel1);
	}

	switch($mode) {
		case "png":
			header('Content-type: image/png');
			imagepng($img);
		break;
		case "jpg":
			header('Content-type: image/jpeg');
			imagejpeg($img);
		break;
		case "gif":
			header('Content-type: image/gif');
			imagegif($img);
		break;
	}
	/* free the memory */
	imagedestroy($img);
	die();
}

imgEncrypt($currentImage, array( 'swapFactor' => 4, 'jumpFactor' => 5 ));

به نظر سورس تصویر رو با کتابخانه GD پی اچ پی با یه متد خاص و مشخص که با فایل استاتیک هم خوانی داشته باشد نکته مهم این جاست تصویر رو بهم میریزد و نمایش میدهد . همان طور هم که از کدینگ پیداست باید در المنت SRC تگ IMG از لینکی به صورت imagesafe.php?id=1 استفاده کرد خوب حال که متوجه شدید در HTML باید مثلا از کد زیر استفاده شود و تا داینامیک فراخوانی شود هر چند در شکل اولیه تنظیم لینک تصویر در فایل پی اچ پی صورت میگیرد .

<img src="imagesafe.php?id=1" />

خوب تا اینجا من و شما متوجه شدیم که با کمک یک تابع پی اچ پی و کمک از کتابخانه GD که به کار رفته و معمولا روی سرور های نصب هست تقییراتی ایجاد کردیم و در خروجی تصویر سالم با تغییرات نمایش داده می شود به تصویر زیر نگاه کنید :

تصویر سمت چپ تصویر اصلی می باشد و تصویر سمت راست تصویریست که بعد از عبور از تابع imgsafe ما ساخته شده خوب حالا چه قدر جالب شد وقتی سورس اصلی به این شکل نمایش داده می شود پس اصلا قابل دانلود نیست خوب چه خوب اما چطوری تو سایت خودمان نمایش دهیم ؟ خوب فراموش نکردید که گفتم فایل داینامیک باید اگر فایل استاتیکی وجود داشته باشد هماهنگ باشد . خوب حالا ما فایل جاوا اسکریپتی مانند کد زیر را در سایت فراخوانی می کنیم :

/**
 * imagesafe. Protect your images
 * Copyright w-labs | Patrick Wied
 * http://w-labs.at
 * http://www.patrick-wied.at
 */

var decoder = (function() {
  		var canvas,
  			ctx;
  		var init = function() {
  			// get all images with a specific class
  			var list = document.getElementsByClassName('encrypted');

  			for (var i = 0; i < list.length; i++) {
  				var entry = list[i];
  				var wrapper = document.createElement('div');
  				wrapper.className = 'imagesafe';
  				var style = entry.style;
  				var pos = 'float:' + (style.float || style.cssFloat) + ';left:' + style.left + 'px;top:' + style.top + 'px;';
  				wrapper.style.cssText = 'width:'+entry.width+'px;height:' + entry.height + 'px;' + pos;
  				var parent = list[i].parentNode;
   				parent.replaceChild(wrapper, entry);
   				wrapper.appendChild(entry);
   				uncrypt(entry, { swapFactor: 4, jumpFactor: 5});
  			}
        uninitialize();
  		};
  		var uncrypt = function(img, config) {
  			if (img) {
  				canvas = document.createElement('canvas');
  				canvas.style.cssText = 'position:absolute;top:0;left:0;'
	  			ctx = canvas.getContext('2d');
	  			var width = canvas.width = img.width;
	  			var height = canvas.height = img.height;
	  			var parent = img.parentNode;
	  			parent.appendChild(canvas);
	  			ctx.drawImage(img, 0, 0);	
  			}else {
  				var width = canvas.width;
  				var height = canvas.height;
  			}
  			var imgData = ctx.getImageData(0, 0, width, height);
  			var data = imgData.data;
  			var dlen = data.length;
  			var plen = 4;
  			var jump = plen * (config.jumpFactor || 4);
  			var swap = plen * (config.swapFactor || 2);

  			for(var i = 4; i < dlen; i += jump) {
  				var d1 = data[i], d2 = data[i+1], d3 = data[i+2], d4 = data[i+3];
  				data[i] = data[i+swap];
  				data[i+1] = data[i+swap+1];
  				data[i+2] = data[i+swap+2];
  				data[i+3] = data[i+swap+3];
  				data[i+swap] = d1;
  				data[i+swap+1] = d2;
  				data[i+swap+2] = d3;
  				data[i+swap+3] = d4;
  			}

  			imgData.data = data;
  			ctx.putImageData(imgData, 0, 0);
  		};
      var uninitialize = function() {
        HTMLCanvasElement.prototype.toDataURL = function() {};
      };

  		return {
  			init: init
  		}
  	}());
	if (window.addEventListener) {
	  window.addEventListener('load', decoder.init, false);
	}
	else if (window.attachEvent) {
	  window.attachEvent('onload', decoder.init );
	}

خوب دیگه اگه برنامه نویس باشید و کد بالا را یه نگاهی انداخته باشید کل داستان را متوجه شدید بله حال فقط کافیست هر تصویری که کد می شود در تگ IMG آن المنت class=encrypted را اضافه کنیم مانند کد زیر :

<img src="imagesafe.php?id=1" class="encrypted" />

خوب فهمیدیم که تابع سورس اصلی رو کد شده ارایه می دهد و فایل استاتیک ما که دقیقا با کدینگ داینامیک ست شده که تصویر به چه شکل ویرایش شود اماده شده و هنگام فراخوانی فایل استاتیک تصویر سالم به نمایش در می آورد و من با چندین نرم افزار تست کردم امنیت نسبت به روشهای رایج اکنون فوق العاده است اما 100% نیست هر چند می توانید حتی واترمارک هم اضافه کنید دیگه همه راه ها رو بر روی دزدان اینترنتی وبسایت خود ببندید . اما چند نکته چون کتابخانه GD به فایل حساسه اگه فایل مثلا png رو به jpg تغییر دهید فایل نمایش داده نمی شود برای این کار می توانید از کدینگ های ساده واسه تشخیص فرمت فایل تصویری ورودی استفاده کنید همچنین شاید مسله دیگر که مد نظر شما باشد مسله واترمارک باشه و این که چطوری بدون نمایش این فایل پی اچ پی لینک های تصویری وبسایت خود به خود از این تابع عبور کنند که من بهترین گزینه را htaccess می دونم و چندین بار امتحان کردم بهترین نتیجه را گرفتم هر چند اگه کاربران واقعا علاقه مند بودند در نظرات ذکر کنند تا توضیحی هم در این بخش داده شود و اما نقطه ضعف این تابع برای نمایش فایل های png بدون پسزمینه می باشد که فعلا کتابخانه GD من شخصا ندیدن بتواند این نوع فایل رو صحیح ویرایش کند اما در آینده شاید چنین شود هر چند با رفتن به سمت جلو و ظاهر شدن تصاویری با فرمت فوق العاده SVG کم کم باید با این فرمت های پیش پا افتاده در صنعت وب خدا حافظی کرد . در آخر نمونه فایل کلاس پیوست شد . خدانگهدار

من سید امیرحسین طــاووســی هستم طــراح و برنامه نویس وب . فـعالیتم را در زمینه کــامپـیوتـر قبل از سـال اول دبـسـتـان شـروع کــردم و تا دوره راهنمایی اطلاعات کاملی از این تکنولوژی بدست آوردم . از ان دوره تا کنون در زمینه های مختلف فعالیت می کنم که مهـم ترین آن برنامه نویسی وب است یکی از عواملی که باعث شد تا به این سمت بیام کـدباز بودن زبان های وب هستش و روز به روز به دانستنیهایم در این زمینه می افزایم. شاد و سرزنده باشید .

رمز فایل ها در بیان باکس : tavousi.name

در صورت مشکل در دانلود فایل ها و یا حذف شدن آن ها ما را مطلع نمایید .

نظرات  (۵)

درود !
لطفا پس از پاسخگویی به ایمیل من اطلاع دهید تا مجددا به وبگاه شما سر بزنم برای ادامه بحث !

روش های مختلفی هستن برای این منظور همونطور که خودتتون هم فرمودید !
حالا یک روش هم مدنظر من هست که قبلا هم اجرا شدهف روشی که مثلا در سایت فیس نما اجرا شده !

تصویر کامل دیده میشه ولی وقتی قصد ذخیره سازی اون رو داشته باشیم، یک تصویر نامفهوم دیگه ای دانلود میشه، تقریبا مثل ماسک میمونه که روی تصویر اصلی قرار گرفته و وقتی ما کلیک میکنیم در واقع روی ماسک کلیک کردیم نه عکس حقیقی ×

ممنون میشم این مورد رو بررسی بفرمایید و در صورت امکان، آموزشی هم قرار بدید ؟

تشکر !
پاسخ:
من چیزی مشاهده نکردم باید لینک بدید . در مورد اسکریپت حمایت از خلیج فارس که در تماس با ما مطرح کردید باید عرض کنم بله مال من بود اما دیگه عملا کاربردی نداره بهتره دنبالش نگردید ...
درود و سپاس بابت پاسخگویی !

آدرس خدمت شما : http://facenama.com/mohsen061

سعی کنید مثلا عکس پروفایل (آواتار) رو ذخیره کنید ؟ می بینید که کلا عکس دیگه ذخیره میشه !

در مورد اسکریپت هم ممنون و کاش از نو اون رو نگراش میکردید، خلیج ما که همیشه پارسی خواهد موند منتها میشه کاربردهای مختلفی رو به اسکریپت نسبت داد، مثلا به عنان یک دیوار خاطرات برای بلاگ و سایت های کوچک !

###

شما به php تسلط دارید ؟  من یک اسکریپت دارم که تقریبا شبیه به میکروبلاگ هست ولی خیلی ساده تر، میخواستم چندتا تغییر در اون بدم، میتونید کمک کنید ؟  حتی با دریافت هزینه ؟

تشکر !
پاسخ:
این یک ترفند خیلی قدیمی هست راحت با view source می توانید کد زیر را مشاهده کنید :
<div style="width:181px; padding:0px; margin:0px; background-image:url('http://facenama.com/i/avatars/1412328526929253.png');"> <img src="http://facenama.com/themes/basic/imgs/space.gif" style="height:150px; width:180px;padding:0px;" class="avatar"> </div>
درود و سپاس !

از کد الگو گرفتم ولی تصویر پروفایل در سایتم نمایش داده نشد، یعنی نمایش داده میشه ولی میوفته پست تصویر دوم و دیده نمیشه، تصویر دوم رو هم با فرمت های مختلف ایجاد  ذخیره کردم ولی باز کاملا سفید نمایش میداد !

این کدهای مربوط به تصویر پروفایل هستن در سایت من :

        <div class="avatar-wrapper">
            <img class="avatar" src="<?php echo $sk['timeline']['avatar_url']; ?>" alt="<?php echo $sk['timeline']['name']; ?>">
            <?php
            if ($sk['logged'] == true && $sk['timeline']['id'] == $sk['user']['id']) {
            ?>
            <div class="avatar-change-wrapper">
                <i class="icon-camera" title="<?php echo $lang['change_avatar_label']; ?>" onclick="javascript:$('.change-avatar-input').click();"></i>
            </div>
پاسخ:
حتما صحیح نصب نکردید همچنین توجه داشته باشید که چون jQuery از rePlace استفاده می کنه در تنظیم کدهای استاتیک باید دقت زیاد به خرج بدهید . 
سلام.
لطفا کد htaccess را هم توضیح بدید...
مخصوصا برای واترمارک کردن تصاویری که سایتهای دیگه بدون اجازه استفاده می کنند! کدهایی پیدا کردم اما کار نمی کنه! (روی لوکال هاست تست کردم) مثل :
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http(s)?://(www\.)?myDomain.com [NC]
RewriteRule \.(jpg|jpeg|png|gif)$ myDomain.com/no.jpg [NC,R,L]

یا
RewriteRule ^([^tn].*\.(gif|jpg|png))$ /images/jreviews/watermark.php?image=$1&watermark=watermark.png [NC]

پاسخ:
باشه من یک پست آموزشی کامل در این زمینه واسه htaccess ارسال می کنم .
با سلام و احترام خدمت شما دوست عزیز

ترفند جالبی هستش...با chrome هم در قسمت Resources چک کردم دیدم اونجا هم به صورت نامفهوم نمایش داده شده...ولی در کل بازم میشه از طریق نرم افزار هایی مثل : offline explorer enterprise معکوس این عمل رو انجام داده و تصاویر سایت رو گرفت ...

راستی این اسکریپت رو اینجا دیده بودم :



http://codecanyon.net/item/imgsafe/5610029?WT.oss_phrase=imagesafe&WT.oss_rank=1&WT.z_author=w-labs&WT.ac=search_thumb

ارسال نظر

ارسال نظر آزاد است، اما اگر قبلا در بیان ثبت نام کرده اید می توانید ابتدا وارد شوید.
شما میتوانید از این تگهای html استفاده کنید:
<b> یا <strong>، <em> یا <i>، <u>، <strike> یا <s>، <sup>، <sub>، <blockquote>، <code>، <pre>، <hr>، <br>، <p>، <a href="" title="">، <span style="">، <div align="">
تجدید کد امنیتی