PDA

View Full Version : اطلاعاتی درباره عکسهای امنیتی



mahdi_negahi
یک شنبه 06 فروردین 1385, 16:53 عصر
سلام دوستان
اگر کسی از عکسهای امنیتی اطلاعاتی دارد لطفا دریغ ننماید

همان عکسهای که در بعضی صفحات Login آورده شده و عددی را نمایش می دهد و ما باید آن عدد را در فیلد مخصوص بنویسیم

البته شاید من اسم درست این تکنولوژی را ندانم لطفا اگر کسی چیزی می داند کمک کند

توجه کد نهایی این تاپیک در آخرین صفحه است

nazaninam
یک شنبه 06 فروردین 1385, 17:24 عصر
چه اطلاعاتی لازم داری من می تونم نحوه ساختنش رو بگم:

mahdi_negahi
یک شنبه 06 فروردین 1385, 17:34 عصر
اگر می شه وقت بزاری و یک اطلاعات کامل بدهی یک دنیا ممنون می شوم

nazaninam
یک شنبه 06 فروردین 1385, 18:02 عصر
این عکس ها معمولا یک رشته از حروف به صورت تصادفی می باشند که در حقیقت به عکس تبدیل شدند و یکم کج و معوج میشند که نشه دوباره به رشته حرف تبدیلشون کرد ...
نحوه کار به این صورت هست که ابتدا یک رشته از حروف تصادفی ایجاد می کنیم این کار در دات نت بوسیله کتابخانه System.Security.Cryptography صورت می گیره
خوب حالا پس از ساخته شدن رشته حروف اونو به عکس تبدیل می کنیم برای اینکار به کتابخانه های زیر نیاز داریم :




Imports System.Drawing.Text 'for font

Imports System.Drawing.Imaging 'for saving the gif

Imports System.Security.Cryptography 'for creating random String





خوب حالا یه تابع تعریف می کنیم برای ساختن رشته حروف تصادفی




Public Function CreateSalt(ByVal size As Integer) As String

' Generate a cryptographic random number using the cryptographic

' service provider

Dim rng As New RNGCryptoServiceProvider

Dim buff(size) As Byte

rng.GetBytes(buff)

' Return a Base64 string representation of the random number

Return Convert.ToBase64String(buff)

End Function


حالا باید عکس مورد نظرمون رو تولید کنیم یه تابع برای تولید عکس ...
ابتدا رشته تولید میشه سپس بوسیله drawstring و کمی چرخش دادن به نوشته ها اون رشته رو به یک تصویر تبدیل میکنیم
شما می تونید فونت و سایز مورد علاقه تون رو بگذارید حتی رنگ نوشته ها رو هم تغیر بدید من از فوتا comic با سایز 10 استفاده کردم ...



Public Function CreateImage(ByVal path As String, ByVal height As Integer, ByVal width As Integer) As String

'Creates a Random Gif file of provided width and height

'the string on the gif file is rotated randomly

'returns the random string painted

Dim r As New Random 'to generate a random angle

Dim salt As String = CreateSalt(4) 'generates a random string

Dim bmp As New Bitmap(width, height, PixelFormat.Format24bppRgb) 'creates a24bit bitmap in memory

Dim g As Graphics = Graphics.FromImage(bmp)

g.TextRenderingHint = TextRenderingHint.AntiAlias 'this will smoothen the Font

g.Clear(Color.Black) 'this clears the background and paints specified color

g.DrawRectangle(Pens.White, 1, 1, width - 3, height - 3)

g.DrawRectangle(Pens.Black, 0, 0, width, height)

Dim mymat As New System.Drawing.Drawing2D.Matrix 'matrix used for rotation transformation()

Dim i As Integer

For i = 0 To Len(salt) - 1 'we will rotate each literal at a specified angle

mymat.Reset() ' matrix should be initialized to identity matrix

mymat.RotateAt(r.Next(-30, 0), New PointF(width * (0.12 * i), height * 0.5))

'rotate at any angle b/w -30 and 0

g.Transform = mymat 'apply the transform

g.DrawString(salt.Chars(i), New Font("Comic Sans MS", 10, FontStyle.Italic), SystemBrushes.ActiveCaptionText, width * (0.12 * i), height * 0.5) 'draw the text onour(image)

g.ResetTransform()

Next

bmp.Save(path, ImageFormat.Gif) 'save the gif at specified path and name

g.Dispose() 'clean up

bmp.Dispose() 'ok the mess is over

Return salt 'return the string painted for verification

End Function



خوب تقریبا کار تمومه عکس رو توی اون PATH که بالا توی ورودی تابع وارد کریم ذخیره کردیم
میمونه نمایش و مقایسه...

برای نمایش عکس ابتدا یک کنترل از نوع iMAGE به اندازه 100 در 200 پیکسل و من آی دی اونو Imag1 گذاشتم داخل صفحه بگذارید
یک textbox با آی دی پیشفرض textbox1 و باتنی با آی دی پیشفرض button1 داخل صفحه میگذاریم
خوب توی ساب روتین لود صفحه عکس و رشته تصادفی رو می سازیم ....




Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs)Handles MyBase.Load

If Not Page.IsPostBack Then

Dim salt As String = CreateImage(Server.MapPath("Random.gif"), 100, 200)

Image1.ImageUrl = Server.MapPath("Random.gif")

Session.Add("salt", salt)

End If

End Sub



مقدار رشته تصادفی رو توی یک session میریزیم که دوباره باهاش کار داریم البته شما هر جا دوست داشتید بریزدش...

خوب تموم شد حالا میتونید هر بلایی سرش بیارید
مثلات وقتی باتن کلیک میشه اگه مقدار داخل textbox با مقدار session برابر بود کاربر رجستر شه اگه نه پیغام خطا بده...




Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

If Not TextBox1.Text.Equals(Session.Item("salt")) Then

'continue registration
Else

' Error

End If
End Sub





منبع planet source code
اگه مشکلی بود بپرسید

mahdi_negahi
یک شنبه 06 فروردین 1385, 18:12 عصر
بابا دمت گرم خیلی باحالی مرسی
دوستان توجه کنند این مقاله را به صورت PDF در می آورم و ابنجا می زارم البته کد #C هم اضافه می شود

راستی نازنین خانم اسم انگلیسی این تکنولوژی چیه

nazaninam
یک شنبه 06 فروردین 1385, 18:18 عصر
اسم لاتینش Image Verification
در ضمن اگه دوستان بان این خطا مواجه شدن:



A generic error occurred in GDI+.



بخاطر وجود درایو NTFS است که میتونید پرمیشن های لازم رو بدید یا اون server.mappath رو به آرس فیزیکی یه درایو دیگه تغییر بدید
من فایل رو هم باسه دریافت گذاشتم خواستید دانلود کنید....

Saeed_Taghvaee
یک شنبه 06 فروردین 1385, 18:27 عصر
البته کد بالا بسیار حرفه ای کار میکنه و تقریبا متدش با دیگر روش ها میخونه ولی در بیشتر روش ها تصویر نهایی بجای ایننکه در یک فایل در سرور ذخیره شه با استفاده از Response.OutputStream یک صفحه در خروجی یک صفحه aspx ذخیره میشه و در تگ ایمیج خاصیت آدرس تصویر رو آدرس صفحه پاس میدهند.
فرض کنید دو کاربر هم زمان سر صفحه لوگین بیان ممکنه که کدی که در تصویر ببیند با چیزی که در سشنشون ثبت شده یکی نباشه برای همین بیشتر از راه حل بالا استفاده میشه

mahdi_negahi
یک شنبه 06 فروردین 1385, 18:29 عصر
سلام یک سوال به دلیل اشنا نبودن با VB

کد زیر چه کار می کند

Dim buff(size) As Byte

مرسی

nazaninam
یک شنبه 06 فروردین 1385, 18:33 عصر
یه آرایه از نوع بایت ... همین سایز هم که به طور پارامتری پاس میشه توی c# اینطوری میشه:




byte[] buff = new byte[size];

mahdi_negahi
یک شنبه 06 فروردین 1385, 18:35 عصر
مرسی خواهر

mahdi_negahi
یک شنبه 06 فروردین 1385, 20:36 عصر
خوب اینم PDF ها

mahdi_negahi
یک شنبه 06 فروردین 1385, 21:06 عصر
یک مشکل چه طوری از تولید بعذی از حروف باید جلوگیری کرد مثل / ^ یا امثال اینا

nazaninam
دوشنبه 07 فروردین 1385, 02:32 صبح
نمیدونم راهی که من استفاده می کنم چقدر منطقیه ولی اینکارو می کنم:
salt.replace("^",nothing)
که توی سی شارپ اینجوری میشه
salt.replace("^", null);
به جای null یا Nothing از "" هم میتونی استفاده کنی

nazaninam
دوشنبه 07 فروردین 1385, 02:33 صبح
می تونی یه لیست از چیزایی که دویت نداری درست کنی بریزشون توی یک آرایه بعد توی یک حلقه همشون رو replace کنی ... اگه راه بهتری به ذهنت میرسه بگو منم بدردم می خوره

mahdi_negahi
دوشنبه 07 فروردین 1385, 09:45 صبح
سلام دوستان من تایع CreateSalt را این طوری تغییر دادم نتیجه خوبی گرفتم


public string CreateSalt(int size)
{
Random r = new Random();
string str;
RNGCryptoServiceProvider rng =new RNGCryptoServiceProvider();
byte[] buff = new byte[size];
rng.GetBytes(buff);
str = Convert.ToBase64String(buff);
for(int i = 0 ; i < str.Length ; i++)
{
switch(str[i])
{
case '=':
str = str.Remove(i,1);
str = str.Insert(i,r.Next(0,9).ToString());
break;
case '/':
str = str.Remove(i,1);
str = str.Insert(i,r.Next(0,9).ToString());
break;
case '\\':
str = str.Remove(i,1);
str = str.Insert(i,r.Next(0,9).ToString());
break;
case '+':
str = str.Remove(i,1);
str = str.Insert(i,r.Next(0,9).ToString());
break;
}
}
return str;
}

mahdi_negahi
دوشنبه 07 فروردین 1385, 09:47 صبح
البته اگر کسی روش بهتر می دونه برای ما بنویسد

Saeed_Taghvaee
دوشنبه 07 فروردین 1385, 10:48 صبح
لازم نیست که حتما از پروایدر امنیتی دات نت استفاده کنی و بعد هم از Base64 این طوری طول رشته خیلی طولانی میشه ! به نظرم یه عدد تصادفی تولید کن وبعد هم این اعداد تصادفی رو که از Range مربوط به کارکتر ها گرفتی رو بریز تو آرایه (ترجیحا به شکل بایت ) بعد هم با System.Text.Encoding.ASCII.GetString اونو به رشته تبدیل کن یا اصلا فقط عدد باشه . به نظرم اگه قرار باشه در قسمت های مختلف یه سایت ازش استفاده شه برای کاربر بازدید کننده راحت ترش اینه که فقط عدد باشه !

mahdi_negahi
دوشنبه 07 فروردین 1385, 10:55 صبح
ساعد جان اگر نی شه کدتو بنویس دستت هم درد نکنه

Saeed_Taghvaee
دوشنبه 07 فروردین 1385, 11:09 صبح
من کد زیر رو تو سایتم نوشتم :


private void Page_Load(object sender, System.EventArgs e)
{
String rnd=Session["num"].ToString();
Request.ContentType="image/jpeg";
Stream outs=Response.OutputStream;
System.Drawing.Image image=(System.Drawing.Image)new Bitmap(52,20);;
Graphics g=Graphics.FromImage(image);
g.Clear(Color.White);
Random r=new Random(255);
Brush bb=Brushes.Blue;
Font f=new Font("Tahoma",(float)10,FontStyle.Bold);
g.DrawString(rnd,f,bb,(float)0,(float)0);
g.Dispose();
image.Save(outs,System.Drawing.Imaging.ImageFormat .Jpeg);
}

mahdi_negahi
دوشنبه 07 فروردین 1385, 11:21 صبح
مرسی دوست عزیز
ایا ایا این کد همون مشکل که در صفحه اول نوشته بودید را دارد

Saeed_Taghvaee
دوشنبه 07 فروردین 1385, 11:43 صبح
به هیچ وجه !! همون طور که میبینید تصویر نهایی در خروجی صفحه ذخیره میشه ، فقط حواستون باشه برای این کد یه صفحه مجزا که توش هیچ تگی به جز (Page) بسازین و این روتین رو توش بنویسین و هر وقت نیاز به تص.یر داشتین در تگ ایمیج اتریبیوت src رو آدرس صفحه پاس بدین

mahdi_negahi
دوشنبه 07 فروردین 1385, 13:27 عصر
ساعد جان اگر می شه بیشتر توضیح بده درباره صفحه که توش هیچ تگی نباشه ....
من درست نفهمیدم
اگر می شه راهنمایی کامل کن
بعدشم این کار بهتره یا این که ما فیزکی تصویر را Save کنیم و چرا

Saeed_Taghvaee
دوشنبه 07 فروردین 1385, 13:57 عصر
نکته :(من سعیدم ولی شما هر جور راحتی صدام کنید !)
منظورم اینه که یه صفحه aspx بساز و هر چی توشه (ازجمله تگBody,Html,Head) پاک کن فقط تگ اصلی Page بمونه چون قراره تصویر رو خروجی نوشته و وجود این تگ باعث میشه خروجی نهایی (که قراره کد بایت های باینری تصویر روش نوشته شه) همراه با تگ ها باشه و قائدتا متن اون صفحه مطابق با باینری نخواهد بود و صفحه کار نمیکنه ! مثلا شما ببین در همین vBulletin که در این سایت استفاده شده آواتار افراد از یک فایل php لود میشه نه از یک فایل تص.یری (http://www.barnamenevis.org/forum/image.php?u=14544&dateline=1142407518)
این کار باعث میشه که تصویری که رو سرور ذخیر میشه فقط یه فایل باشه برای همین با ورود چند فرد دیگر به همان صفحه در یک فاصله زمانی کوتاه(چند میلی ثانیه) ممکنه همان یه تصویر نمایش داده شه ولی این روش تصویر رو برای هر کلاینت میفرسته و با هرگونه تعداد افراد قاطی نمیکنه!! اگه دقت کنی در اکثر وب پرتال ها هم از این روش بجای استفاده از تصویر در مسیر اصلی سرور استفاده میشه !

PrinceDotNet
دوشنبه 07 فروردین 1385, 14:31 عصر
می تونید از Handler ها استفاده کنی

PrinceDotNet
دوشنبه 07 فروردین 1385, 14:36 عصر
این هم کد خوبیه که برای دات نت 2 هستش.

در ضمن اسمش سرویس Captcha است.

mahdi_negahi
دوشنبه 07 فروردین 1385, 14:50 عصر
خوب من این کار را کردم سعید جان یعنی یک Web Form به پروژه اضافه کردم بعد تمام تگهایش را پاک کردم و فقط این خط ماند


<%@ Page language="c#" Codebehind="WebForm1.aspx.cs" AutoEventWireup="false" Inherits="E_Clinic.WebForm1" %>

حال در صفحه #C این روالی که شما نوشتید را نوشتم ( البته در Page_Load)
حال مشکل اینجاست که در صفحه login.aspx این عکس چطوری نمایش داده شود

Saeed_Taghvaee
دوشنبه 07 فروردین 1385, 14:56 عصر
<img src=Picture.aspx>
با کد بالا تصویر براحتی لود خواهد شد :چشمک:

mahdi_negahi
دوشنبه 07 فروردین 1385, 15:02 عصر
آقا سعید نشد میشه یک ID Yahoo بذاری

Saeed_Taghvaee
دوشنبه 07 فروردین 1385, 17:54 عصر
نکته :منظورم از Picture.aspx ادرس همون WebForm هست !
ولی در هر صورت آیدی من : saeed_online2006 هست اگه بازم حل نشد من درخدمتم !

mahdi_negahi
دوشنبه 07 فروردین 1385, 20:00 عصر
بابا سعید جون مثل اینکه مارو دستکم گرفتی :چشمک:

mahdi_negahi
چهارشنبه 09 فروردین 1385, 00:46 صبح
کسی نیست که بدونه چرا راه حل سعید درست جواب نمی ده

Saeed_Taghvaee
چهارشنبه 09 فروردین 1385, 07:08 صبح
عجیبه :متعجب: !!
خب بذار کدی که خودم نوشتم رو دقیقا بگم
صفحه ی نمایش تصویر و روال لود که دقیقا همون کدی بود که بهت دادم اما جایی که اون تصویر رو صدا میزنی ابتدا همون سشن که توش عدد حرف یا کارکتر های تصادفی نوشته میشد رو ذخیر میکنم و بعد خاصیت ادرس تصویر رو ادرس صفحه پاس میدم. یعنی این :
(Login.aspx)

<IMG height="20" src="ImageSecr.aspx" width="52" border="0"><BR>
(Login.aspx.cs)

if (!Page.IsPostBack)
{
Random ra = new Random();
int Codes = ra.Next(100000, 900000);
Session.Add("num", Codes);
}
البته اینو وقتی که تلاش کاربر ناموفق بود و داده های ورودی اشتباه بودند دقیقا کد بالا رو تکرار میکنم که تصویر آپ دیت شه.

mahdi_negahi
چهارشنبه 09 فروردین 1385, 21:36 عصر
خوب دوستان این تاپیک به سرانجام رسید من کد نهایی و تست شده را برایتان می گذارم اگر به درتان خورد من و آقا سعید و نازنین خانم را دعا کنید:چشمک:

1- یک صفحه وارد پروژه کنید و تمام تگهای HTML وغیره را بجز تگ Page را حذف کنید یعنی تگ زیر را

<%@ Page language="c#" Codebehind="CreateImage.aspx.cs" AutoEventWireup="false" Inherits="E_Clinic.ImageVerification.CreateImage" %>


2- تابعی به نام CreateString که مقدار بازگشتی از نوع رشته دارد را اضافه کنید و کد زیر را برایش بنویسید :


private string CreateString(int Length)
{
Random r = new Random();
string str;
RNGCryptoServiceProvider rng =new RNGCryptoServiceProvider();
byte[] buff = new byte[Length];
rng.GetBytes(buff);
str = Convert.ToBase64String(buff);
str = str.ToUpper();
for(int i = 0 ; i < str.Length ; i++)
{
switch(str[i])
{
case '=':
str = str.Remove(i,1);
str = str.Insert(i,r.Next(0,9).ToString());
break;
case '/':
str = str.Remove(i,1);
str = str.Insert(i,r.Next(0,9).ToString());
break;
case '\\':
str = str.Remove(i,1);
str = str.Insert(i,r.Next(0,9).ToString());
break;
case '+':
str = str.Remove(i,1);
str = str.Insert(i,r.Next(0,9).ToString());
break;
case 'I':
str = str.Remove(i,1);
str = str.Insert(i,r.Next(0,9).ToString());
break;
}
}
Session.Add("salt",str);
return str;
}

توجه : روال بالا رشته ای را به طور تصادفی درست کرده و آن را درون Session ی به نام salt می ریزد تا شما هر کجا که می خواهید مقدار عکس با مقدار ورودی کاربر مقایسه کنید در ضمن این مقداری که در session ریخته شده به صورت حروف بزرگ است

3- در روال Page_Load کد زیر را بنویسید

Random r = new Random();
string str = CreateString(3);
Brush myBrush = new SolidBrush(Color.Black);
Request.ContentType="image/jpeg";
Stream outs=Response.OutputStream;
System.Drawing.Image image=(System.Drawing.Image)new Bitmap(140,35);
Graphics g=Graphics.FromImage(image);
g.Clear(Color.LightPink);
System.Drawing.Drawing2D.Matrix myMatrix = new System.Drawing.Drawing2D.Matrix();
for(int i = 0; i < str.Length ; i++)
{
myMatrix.Reset();
PointF F = new PointF(140*(0.18f*(i+1f)),35* 0.5f);
myMatrix.RotateAt(r.Next(-40,40),F);
g.Transform = myMatrix;
g.DrawString(str[i].ToString(),new Font("Arial",11,FontStyle.Regular),myBrush,140*(0.18f*(i+1f)), 35*0.3f);
g.ResetTransform();
}
image.Save(outs,System.Drawing.Imaging.ImageFormat .Jpeg);
g.Dispose();
image.Dispose();
4- وب فرمی را در پروژه اضافه کرده و یک کنترل Image به آن اضافه کنید و خاصیت ImageUrl یا scr آن را مساوی صفحه ای که در بالا گفتم قرار دهید (صفحه ای فقط تگ Page داشت)

5 - برای اینکه شما چک کنید ورودی کاربر مساوی مقدار عکس است به صورت زیر عمل می کنید

if(txtImageVar.Text.ToUpper() == Session["salt"].ToString().ToUpper())
{
کد
}

bardia goharbin
پنج شنبه 10 اسفند 1385, 12:21 عصر
واقعا کدهاى محشری بود، ولی من تلاش کردم این قابلیت را به CreateUserWizard بصورت Custom اضافه کنم که متاسفانه نتوانستم، اگر دوستان این قابلیت را در CreateUserWizard اضافه کرده اند یا نمونه کاملی از CreateUserWizard که کاملترش کرده اند را دارند ممنون میشوم ارسال کنند. (توی این زمینه واقعا محتاجم)
در ضمن آیا میشود به جای رنگی که به Background تصویر داده اید، تصویر دیگری را بصورت Background درنظر بگیریم یا خیر؟

Emerlad_64
یک شنبه 21 خرداد 1391, 17:53 عصر
سلام ميشه بيشتر در مورد خطاي "A generic error occurred in GDI+." توضيح بديد.دقيقا چطوري ميشه پروميشن رو تغيير داد؟