PDA

View Full Version : الگوریتم رمزنگاری MD5



younes-98
سه شنبه 15 بهمن 1387, 19:25 عصر
unit md5;

interface

type
MD5Digest = array[0..15] of Byte;
MD5State = array[0..3] of LongWord;
MD5Buffer = array[0..63] of Byte;

TMD5 = class
private
FState: MD5State;
FCount: Int64;
FBuffer: MD5Buffer;
public
constructor Create;
procedure Update(const Input; Length: Cardinal);
function Final: MD5Digest;
end;


function MD5Message(const Message; Length: Cardinal): MD5Digest;
function MD5String(const S: string): MD5Digest;
function MD5File(const FileName: string): MD5Digest;

function MD5Print(const D: MD5Digest): string;


implementation

{$IFDEF MSWINDOWS}
uses
Windows;
{$ENDIF}


function ROL(X: LongWord; Count: Integer): LongWord;
{$IFDEF PUREPASCAL}
begin
Result := (X shl Count) or (X shr (32 - Count));
end;
{$ELSE}
asm
MOV ECX,EDX
ROL EAX,CL
end;
{$ENDIF}


type
MD5Iters = 0..63;

var
k: array[MD5Iters] of Integer;
T: array[MD5Iters] of LongWord;
s: array[MD5Iters] of Integer;

procedure InitLUTs;
const
A: array[0..15] of Integer =
(
7, 12, 17, 22,
5, 9, 14, 20,
4, 11, 16, 23,
6, 10, 15, 21
);
var
I: Integer;
begin
for I := 0 to 63 do
begin
case I of
0..15: k[I] := I;
16..31: k[I] := (5 * I + 1) and $f;
32..47: k[I] := (3 * I + 5) and $f;
48..63: k[I] := (7 * I) and $f;
end;
T[I] := Trunc(Abs(Sin(I + 1)) * $100000000);
s[I] := A[I shr 2 and $c or I and $3];
end;
end;

// MD5 basic transformation. Transforms state based on block.

procedure Transform(var State: MD5State; const Block);
var
X: array[0..15] of LongWord absolute Block;
a, b, c, d, i, f, temp: LongWord;
begin
f := 0;
a := State[0];
b := State[1];
c := State[2];
d := State[3];
for i := 0 to 63 do
begin
case i of
0..15: f := d xor (b and (c xor d));
16..31: f := c xor (d and (b xor c));
32..47: f := b xor c xor d;
48..63: f := c xor (b or (not d));
end;
temp := d;
d := c;
c := b;
Inc(b, ROL(a + f + X[k[i]] + T[i], s[i]));
a := temp;
end;
Inc(State[0], a);
Inc(State[1], b);
Inc(State[2], c);
Inc(State[3], d);
end;


{ TMD5 }

constructor TMD5.Create;
begin
FState[0] := $67452301;
FState[1] := $efcdab89;
FState[2] := $98badcfe;
FState[3] := $10325476;
end;

type
Bytes = array[0..0] of Byte;

procedure TMD5.Update(const Input; Length: Cardinal);
var
I, Index, PartLen: Cardinal;
begin
Index := FCount and $3f;
Inc(FCount, Length);
PartLen := 64 - Index;
if Length >= PartLen then
begin
Move(Input, FBuffer[Index], PartLen);
Transform(FState, FBuffer);
I := PartLen;
while I + 63 < Length do
begin
Transform(FState, Bytes(Input)[I]);
Inc(I, 64);
end;
Index := 0;
end
else
I := 0;
Move(Bytes(Input)[I], FBuffer[Index], Length - I);
end;

function TMD5.Final: MD5Digest;
var
BitLength: Int64;
Padding: MD5Buffer;
PadLen: Integer;
begin
BitLength := FCount shl 3;
PadLen := (119 - FCount and $3f) and $3f + 1;
FillChar(Padding, PadLen, 0);
Padding[0] := $80;
Update(Padding, PadLen);
Update(BitLength, SizeOf(Int64));
Result := MD5Digest(FState);
Free;
end;


// ----------------------------------------------------------------------------

function MD5Message(const Message; Length: Cardinal): MD5Digest;
begin
with TMD5.Create do
try
Update(Message, Length);
Result := Final;
except
Free;
raise;
end;
end;

function MD5String(const S: string): MD5Digest;
begin
Result := MD5Message(Pointer(S)^, Length(S));
end;

function MD5File(const FileName: string): MD5Digest;
{$IFDEF MSWINDOWS}
var
FileHandle: THandle;
MapHandle: THandle;
ViewPointer: Pointer;
{$ENDIF}
begin
FillChar(Result, SizeOf(MD5Digest), 0);
{$IFDEF MSWINDOWS}
FileHandle := CreateFile(PChar(FileName), GENERIC_READ, FILE_SHARE_READ or
FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL or
FILE_FLAG_SEQUENTIAL_SCAN, 0);
if FileHandle <> INVALID_HANDLE_VALUE then
try
MapHandle := CreateFileMapping(FileHandle, nil, PAGE_READONLY, 0, 0, nil);
if MapHandle <> 0 then
try
ViewPointer := MapViewOfFile(MapHandle, FILE_MAP_READ, 0, 0, 0);
if ViewPointer <> nil then
try
Result := MD5Message(ViewPointer^, GetFileSize(FileHandle, nil));
finally
UnmapViewOfFile(ViewPointer);
end;
finally
CloseHandle(MapHandle);
end;
finally
CloseHandle(FileHandle);
end;
{$ENDIF}
end;


function MD5Print(const D: MD5Digest): string;
const
Digits: array[0..15] of Char =
('0','1','2','3','4','5','6','7','8','9','a','b',' c','d','e','f');
var
I: Integer;
TempStr: string[32];
begin
TempStr := '';
for I := 0 to 15 do
TempStr := TempStr + Digits[D[I] shr 4] + Digits[D[I] and $f];
Result := TempStr;
end;


initialization
InitLUTs;

end.

Batman
سه شنبه 15 بهمن 1387, 21:18 عصر
با تشکر
دوست عزیز ممکنه طریقه استفاده از unit و همچنین اینکه چجوری باید چکش کرد رو توضیح بدید؟
ممنونم

younes-98
جمعه 18 بهمن 1387, 18:16 عصر
معرفی الگوریتم MD5

Hash چیست ؟
یک توضیح مختصر در مورد کد گزاری و روش های مختلف :
روش های مختلفی برای کد گزاری وجود دارد مانند توابع و الگوریتم های Randomize و Hash و ...
معمولا هدف اصلی از کد گزاری دو گزینه میباشد
1- امنیت
2- ایجاد کلید های منحصر بفرد

در واقع این دو مورد پر کاربرد ترین موارد استفاده از کد گزاری میباشد
توضیح :
برای ایجاد امنیت در برنامه های مختلف از روش های کد گزاری استفاده میشود ، برای مثال در ذخیره پسورد یوزر های سایتها
مثالی که برای ایجاد کلید های منحصر به فرد میشه زد در امضا های اینترنتی میباشد
برای ایجاد امضا هایی که به صورت منحصر به فرد و بدون تکرار باشند از این روش ها استفاده میشود
برای معرفی Hash سعی میکنم با معرفی MD5 مفهوم اصلی Hash را عنوان کنم

هش (Hash, Hash Code, Digest, Message Digest هم نامیده می شود) را می توان به صورت اثر انگشت دیجیتالی یک داده در نظر گرفت. با این روش شما می توانید رشته ای اندازه-ثابت (fixed length) از یک داده به دست آورید که با روش های ریاضی به صورت &quot;یک طرفه&quot; رمزنگاری شده است
منظور از &quot;یک طرفه&quot; این مفهوم است که قابل برگشت نمیباشد
برای مثال فرض کنید فرمول ما X+2 باشد ! و برای ورودی مانند 3 خروجی ما برابر 5 خواهد بود
حال اگر شما 5 را در اختیار داشته باشید می توانید مقدار اولیه را به راحتی با فرمول معکوس Y-2 بدست آورید !
در روش های &quot;یک طرفه&quot; این امکان وجود ندارد ...

کشف رشته اصلی از رشته هش آن (عملیات معکوس) به صورت کارا تقریبا غیر ممکن است. نکته دیگر اینکه هر داده یک رشته هش شده کاملا منحصر به فرد ایجاد می کند . البته ما داریم در مورد Hash به صورت حرفه ای بحث میکنیم ! در الگوریتم های ساده و آموزشی احتمال تکرار بسیار بالا میباشد ! اما همان طور که گفته شد ما در مورد الگوریتم های حرفه ای صحبت میکنیم ، که احتمال تکرار در آن وجود ندارد ( ما با معرفی الگوریتم حرفه ای MD5 هش را معرفی میکنیم )

در الگوریتم MD5 احتمال وجود تکرار و تصادف وجود ندارد و تمام مقادیر منحصر به فرد میباشد
البته در مقاله ای احتمال یکی شدن رشته های هش دو رشته متفاوت در الگوریتم MD5 یک در 3.4028236692093846346337460743177e+38 عنوان شده بود ! که در واقع می توان گفت احتمال برابر 0 میباشد
هنوز من جایی ندیدم که دو مقدار حاوی تکرار و تصادف و برای این الگوریتم عنوان کنند

این خواص ، هش کردن را به روشی کارا و ایده آل برای ذخیره سازی کلمات عبور در برنامه های شما تبدیل می کند. چرا؟ برای این که حتی اگر یک نفوذگر(Hacker) بتواند به سیستم و بانک اطلاعاتی شما نفوذ کند و بخشی از اطلاعات شما را به دست آورد (شامل کلمات عبور هش شده) نمی تواند کلمات عبور اولیه را از روی آن ها بازیابی کند.


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


شناسایی اعضا با استفاده از Hash :
تا کنون نشان داده ایم که بازیابی کلمه عبور اصلی از روی رشته هش تقریبا غیر ممکن است ، خب چگونه برنامه های ما تشخیص دهند که کلمه عبور وارد شده توسط کاربر صحیح است ؟ به سادگی ! با تولید رشته هش کلمه عبور وارد شده توسط کاربر و مقایسه آن با رشته هش ذخیره شده در رکورد بانک اطلاعاتی مربوط به کاربر می توانید متوجه شوید که آیا دو رشته با هم برابرند یا نه

Hash یک عمل خلاصه سازی (digest ) را روی جریان ورودی انجام می دهد نه یک عمل رمز نگاری (encryption) .
Encryption داده را از یک متن صریح (Clear text) به یک متن برمز در آورده تبدیل می کند (Cipher text). encryption ک عمل دو طرفه می باشد . که هرچه حجمClear text بیشتر باشد حجم Cipher text نیز بیشتر می شود.


Hashe ها جریان داده ورودی را به یک خلاصه کوچک تبدیل می کنند. که این یک عمل یک طرفه(غیر قابل بازگشت) می باشد. و جریان داده ورودی آنها با هر حجمی که باشد خروجی یک مقدار ثابت میشود.

این الگوریتم یک رشته با طول متفاوت را به عنوان ورودی می گیرد و یک &quot;خلاصه پیام MD5&quot; یا &quot;اثر انگشت&quot; با طول 128 بیت می سازد.

برای مثال اگر شما این یک &quot;کلمه&quot; را به الگوریتم دهید ، و یا کل این خط را و یا کل این پاراگراف را ، در نهایت در هر 3 مورد خروجی 128 بیت میباشد


برای مثال یکی از کاربرد های هش تشخیص درستی یک فایل Verifying file integrity میباشد
برای مثال زمانی که یک فایل با حجم بالا را دانلود می نماییم می توانیم با به دست آوردن مقدار MD5 آن فایل توسط دستور md5sum و مقایسه آن با مقدار Md5 داده شده توسط سایت مورد نظر از درستی فایلمان اطمینان حاصل کنیم.

از کاربرد های دیگر آن نشانه گذاری اسناد به روش digitally (امضاهای digitally) میباشد



Collision (تصادف) در Hash
البته معنی صحیح Collision &quot;تصادم&quot; و &quot;برخورد&quot; میباشد ! اما از اونجایی که سر کلاس &quot;تصادف&quot; گفته شده ما هم میگیم &quot;تصادف&quot; ...

زمانی که مقدار Hash دو ورودی متفاوت یکسان باشند می گوییم Collision رخ داده است.
اما تا کنون هیچ موردی از Collision دیده نشده است
( البته همان طور که در بالا گفته شد ما در مورد هش های حرفه ای بحث میکنیم ، نه الگوریتم های ساده آموزشی ... ) .
این امر از این حقیقت ناشی می شود که تعداد مقادیر یک الگوریتم hash بسیار زیاد می باشند.برای مثال یک Hash 128 بیتی میتواند 3.4 x 1038
مقدار ممکن داشته باشد.که معادل 340,282,366,920,938,463,463,374,607,431,768,211,45 6 میباشد.


، محبوب ترین آنها که مورد استفاده برنامه نویسان هستند MD5 و SHA-1 می باشند. سیستم های قدیمی تر از( DES(Data Encryption Standard استفاده می کردند. این روش 56 بیتی دیگر یک روش قوی هش کردن محسوب نمی گردد. ، الگوریتم های قوی تری مانند SHA-256 و SHA-512 برای موارد خاص مانند امضاهای دیجیتالی توصیه می گردد ولی برای هش کردن کلمات عبوردر برنامه های امروزی SHA-1 هنوز سطح امنیت بسیار خوبی را فراهم می کند.
SHA مخفف Secure hash algorithm میباشد

البته در حال حاضر MD5 کاربرد زیادی پیدا کرده است ، و برای ذخیره رمز های عبور از آنها استفاده میشود ( برای سایت DpiGuide نیز از همین الگوریتم استفاده شده است ...! )

الگوریتم MD5 توسعه ای از الگوریتم MD4 می باشد با این تفاوت که MD5 کمی کندتر از MD4 عمل می کند اما در طراحی آن بسیار محافظه کارانه عمل شده است.
MD5 به این دلیل طراحی شد که حس کردند MD4 به عنوان سرعت بالایی که داشت پذیرفته شده و از امنیت بالایی در شرایط بحرانی برخوردار نمی باشد. MD4 برای سرعت بالا طراحی شده ولی احتمال شکست آن در رمز کردنی موفق وجود دارد. MD5 کمی در سرعت کند شده با این تفاوت که بیشترین امنیت را داراست

الگوریتم MD5 به تنهایی نیاز به یک بحث طولانی دارد ، که در صورتی که علاقه داشتید همینجا درخواست بدید تا در مورد اون هم بحث بشه



سوالی که ممکن است برای شما به وجود بیاید این است که سایت هایی دیده اید که برای مثال مخصوص Crack کردن MD5 میباشد ! تا شما مقدار Hash شده را بدهید و مقدار اولیه را دریافت کنید ..!
اما مگر گفته نشد که MD5 یک الگوریتم &quot;یک طرفه&quot; و غیر قابل برگشت میباشد ! پس این سایت ها به چه شکلی کار می کنند !؟
پاسخ : این سایت ها در واقع MD5 را Crack نمی کنند ، این سایت ها Database هایی از هش ها دارند
برای مثال فرد سازنده وب سایت ( یک آدم بیکار ...! ) میاد از 0 تا 999 را هش می کند و داخل Database مقدار ورودی و خروجی را ذخیره میکند ! حال اگر هشی که شما به سایت میدهید در لیست اون باشه مقدار و از لیست خودش به شما میده

مثال این می مونه که من نمی تونم ضرب کنم ! کل جدول ضرب و یک جا می نویسم ! و هر وقت شما سوال کنید ، اگر در جدول من بود به شما جواب و میدم !

نوشته شده توسط : احمد سمیعی

younes-98
جمعه 18 بهمن 1387, 18:47 عصر
شرمنده از اینکه دیر پاسخ دادم
برای استفاده از این یونیت میتونید یک یونیت جدید ایجاد کنید بانام md5 و کد الگوریتم md5 را در آن کپی کنید.
در این یونیت چهار تابع اصلی و کاربردی وجود دارد که عبارتند از :

function MD5Message(const Message; Length: Cardinal): MD5Digest;
function MD5String(const S: string): MD5Digest;
function MD5File(const FileName: string): MD5Digest;
function MD5Print(const D: MD5Digest): string;



یک مثال در محیط دلفی می تواند اینگونه باشد :


procedure TForm1.Button1Click(Sender: TObject);
var
hold:MD5Digest;
begin
hold:=MD5String('younes');
Edit1.text:=MD5Print(hold);
end;

امید امرایی
شنبه 19 بهمن 1387, 19:05 عصر
با دلفی 2007 و 2009 که بنده تست کردم مشکل داشت. در هر دو


123456 = 11b4f806ba5e6b4ff53880fec21b0473

Batman
دوشنبه 21 بهمن 1387, 11:00 صبح
هر چی که وارد می کنم یه کد برمیگردونه.

یعنی تمامی کدهای برگردونده شده شبیه به همه

kianoosh59
چهارشنبه 09 اردیبهشت 1388, 02:42 صبح
متشکر........................................ ....................

SirMehdi
چهارشنبه 12 اسفند 1388, 22:47 عصر
با سلام وتشکر
میشه راجب الگوریتم های دوطرفه هم اطلاعاتی بدین و یه نمونه معرفی کنین که تو دلفی جواب بده

vcldeveloper
پنج شنبه 13 اسفند 1388, 00:22 صبح
میشه راجب الگوریتم های دوطرفه هم اطلاعاتی بدین
تولید هش یک فرآیند یک طرفه هست؛ اگر شما دنبال چیزی می گردید که دوطرفه باشه، باید برید دنبال الگوریتم های رمزنگاری، نه تولید هش.

در عنوان این تاپیک هم به اشتباه گفته شده الگوریتم رمزنگاری MD5، باید گفته میشد الگوریتم تولید هش کد MD5.

Exception
پنج شنبه 13 اسفند 1388, 01:15 صبح
ممنون از توضیحاتتون. فقط چند نکته:


در الگوریتم MD5 احتمال وجود تکرار و تصادف وجود ندارد و تمام مقادیر منحصر به فرد میباشد
البته در مقاله ای احتمال یکی شدن رشته های هش دو رشته متفاوت در الگوریتم MD5 یک در 3.4028236692093846346337460743177e+38 عنوان شده بود ! که در واقع می توان گفت احتمال برابر 0 میباشد
هنوز من جایی ندیدم که دو مقدار حاوی تکرار و تصادف و برای این الگوریتم عنوان کنند
البته وجود داره چنین رشته هایی. اینجا رو ببینید: http://www.mathstat.dal.ca/~selinger/md5collision/
برای SHA1 هنوز پیدا نشده ولی انتظار میره بزودی بشه: http://valhenson.livejournal.com/42323.html


سیستم های قدیمی تر از( DES(Data Encryption Standard استفاده می کردند. این روش 56 بیتی دیگر یک روش قوی هش کردن محسوب نمی گردد.
یک نکته کوچولو: DES ربطی به هش نداره!