หน้าแรก > คุย Linux > การเข้ารหัสแบบ MD5 ที่นิยมกัน

การเข้ารหัสแบบ MD5 ที่นิยมกัน

มิถุนายน 11, 2011 ใส่ความเห็น Go to comments

ทั่วไปแล้ว MD5 (Message-Digest algorithm 5) ถูกนำมาใช้เป็น แฮชฟังก์ชัน (hash function) ในการเข้ารหัสลับ (cryptography) อย่างแพร่หลาย เช่นการเก็บรหัสพาสเวิร์ด และนอกจากนี้ยังมีการนำมาใช้ในการตรวจสอบความสมบูรณ์ของไฟล์ (Md5sum) แต่ถึงกระนั้นก็มีการพบว่า MD5 นั้นไม่เป็นแฮชฟังก์ชันที่ ป้องกันการทับซ้อน (collision resistant) จึงไม่เหมาะสมที่จะนำมาใช้ในแอปพลิเคชันบางอย่างเช่น SSL หรือ Digital Signature

อัลกอริทึม

เราจะเริ่มจากการสมมติให้มีอินพุทเป็นข้อความ M ขนาด b-bit ซึ่ง b เป็นจำนวนเต็มที่ไม่ติดลบ ไม่จำเป็นต้องหาร 8 ลงตัว และมีความยาวได้ไม่จำกัด ซึ่งจะเขียนใหม่ได้เป็น m_0 m_1 m_2 … m_b-1 จากนั้นจะทำการหา MD5 โดยการผ่านขั้นตอนต่อไปนี้

 1. เติมบิตท้าย

เติม “ 10 ” ท้ายข้อความแล้ว เติม “ 0 ” ไปเรื่อยๆ จนกว่าข้อความจะมีขนาดที่คอนกลูเอนกับ 448 (mod 512)

 2. เติมขนาดข้อความ

เติมขนาดของข้อความความยาว 64 บิต ท้ายข้อความ หากขนาดของข้อความใหญ่เกินที่ 64 บิตจะเก็บได้ก็ให้ใช้ 64 บิตหลังของขนาดเท่านั้น สุดท้ายจะได้ข้อความที่แต่งเติมแล้วมีขนาดที่สามารถหาร 512 ลงตัวพอดี นั่นคือจะสามารถแบ่งข้อความได้เป็นชุด ชุดละ 512 บิต หรือ 32 ไบต์ หรือ 16-word block

 3. กำหนดค่าเริ่มต้นของ MD Buffer

ตั้งค่าเริ่มต้นของ buffer ขนาด 32 บิต 4 ตัวดังนี้

A = 0x67452301 , B = 0xEFCDAB89 , C =0x98BADCFE , D = 0x76543210

4. คำนวณข้อความใน 16-word block

ลำดับแรกเราจะกำหนดฟังก์ชันรับอินพุท 32 บิต และเอาต์พุต 32 บิต ดังนี้

F (X,Y,Z) = (X\wedge{Y}) \vee (\neg{X} \wedge{Z})
G (X,Y,Z) = (X\wedge{Z}) \vee (Y \wedge \neg{Z})
H (X,Y,Z) = X \oplus Y \oplus Z
I (X,Y,Z) = Y \oplus (X \vee \neg{Z})

\oplus, \wedge, \vee, \neg แทนการดำเนินการ XOR, AND, OR และ NOT ในขั้นตอนนี้ยังต้องใช้ ตารางขนาด 64 ช่อง T[1…64] ซึ่ง T[i] สามารถหาค่าได้จาก ⌊ 2^32 x |sin ⁡i | ⌋ โดย i มีค่าเป็นเรเดียน จากนั้นทำตามอัลกอริทึมดังนี้

   //ดำเนินการทุก 16-word block
   For i = 0 to N/16-1 do
    //คัดลอก block ที่ i เก็บไว้ที่ X
    For j = 0 to 15 do
      Set X[j] to M[i*16+j].
    end /* of loop on j */

     // เก็บ A ใน AA, B ใน BB, C ใน CC, และ D ใน DD
    AA = A
    BB = B
    CC = C
    DD = D

    // รอบที่ 1
    /* ให้ [abcd k s i] แทน
         a = b + ((a + F (b,c,d) + X[k] + T[i]) <<< s)
         สัญลักษณ์ <<< แทน left rotate
    */
    // ดำเนินการ 16 ครั้งดังนี้
    [ABCD  0  7  1]  [DABC  1 12  2]  [CDAB  2 17  3]  [BCDA  3 22  4]
    [ABCD  4  7  5]  [DABC  5 12  6]  [CDAB  6 17  7]  [BCDA  7 22  8]
    [ABCD  8  7  9]  [DABC  9 12 10]  [CDAB 10 17 11]  [BCDA 11 22 12]
    [ABCD 12  7 13]  [DABC 13 12 14]  [CDAB 14 17 15]  [BCDA 15 22 16]

     // รอบที่ 2
    /* ให้ [abcd k s i] แทน
         a = b + ((a + G (b,c,d) + X[k] + T[i]) <<< s) */
    // ดำเนินการ 16 ครั้งดังนี้
    [ABCD  1  5 17]  [DABC  6  9 18]  [CDAB 11 14 19]  [BCDA  0 20 20]
    [ABCD  5  5 21]  [DABC 10  9 22]  [CDAB 15 14 23]  [BCDA  4 20 24]
    [ABCD  9  5 25]  [DABC 14  9 26]  [CDAB  3 14 27]  [BCDA  8 20 28]
    [ABCD 13  5 29]  [DABC  2  9 30]  [CDAB  7 14 31]  [BCDA 12 20 32]

     // รอบที่ 3
    /* ให้ [abcd k s i] แทน
         a = b + ((a + H (b,c,d) + X[k] + T[i]) <<< s) */
    // ดำเนินการ 16 ครั้งดังนี้
    [ABCD  5  4 33]  [DABC  8 11 34]  [CDAB 11 16 35]  [BCDA 14 23 36]
    [ABCD  1  4 37]  [DABC  4 11 38]  [CDAB  7 16 39]  [BCDA 10 23 40]
    [ABCD 13  4 41]  [DABC  0 11 42]  [CDAB  3 16 43]  [BCDA  6 23 44]
    [ABCD  9  4 45]  [DABC 12 11 46]  [CDAB 15 16 47]  [BCDA  2 23 48]

     // รอบที่ 4
    /* ให้ [abcd k s i] แทน
         a = b + ((a + I (b,c,d) + X[k] + T[i]) <<< s) */
    // ดำเนินการ 16 ครั้งดังนี้.
    [ABCD  0  6 49]  [DABC  7 10 50]  [CDAB 14 15 51]  [BCDA  5 21 52]
    [ABCD 12  6 53]  [DABC  3 10 54]  [CDAB 10 15 55]  [BCDA  1 21 56]
    [ABCD  8  6 57]  [DABC 15 10 58]  [CDAB  6 15 59]  [BCDA 13 21 60]
    [ABCD  4  6 61]  [DABC 11 10 62]  [CDAB  2 15 63]  [BCDA  9 21 64]

     //นำค่าที่ได้กลับไปบวกกับค่าเดิม
    A = A + AA
    B = B + BB
    C = C + CC
    D = D + DD
  end // ของวงวน i

5. แสดงเอาต์พุต

ค่ารหัสที่ได้จะเก็บอยู่ในสมารถแสดงได้โดยนำเลขฐาน 16 ของ A, B, C, D มาต่อกัน

ตัวอย่างการใช้งานในโปรแกรมต่างๆ

<?php

$salt = md5(“1234567890ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz”);
$password = hash( ‘MD5’,$salt );
$hash = $password . $salt;
$rand = rand(1, 256)%4;

for ( $i = 0; $i < $rand; $i++ ) {
  $hash = hash(‘md5’,$hash );
}
echo $hash, ‘<br>’;
echo (microtime(1)-$time)*10000,’: time in ms’;
?>

ในภาษา C++ มีการเพิ่มฟังก์ชั่นโดยการเรียกไลบารี md5.c

#include <iostream>
#include “md5.h”

using namespace std;

int main(int argc, char *argv[])
{
    cout << “md5 of ‘grape’: ” << md5(“grape”)<<endl;
    return 0;
}

ผลลัทธ์ของโปรแกรม:
md5 of ‘grape’: b781cbb29054db12f88f08c6e161c199

ส่วนของ md5.h โหลดได้

ตัวอย่างใน C#

// C# sample code to create an MD5 hash.
private void HashMD5_Click(object sender, System.EventArgs e)
{
Chilkat.Crypt crypt = new Chilkat.Crypt();
crypt.UnlockComponent(“TempCode”);

// Generate some byte data.
byte[] inData = new byte[1000];
int i;
for (i=0; i<1000; i++)
{
inData[i] = Convert.ToByte(i % 255);
}

// Create an MD5 hash.
byte[] hash = crypt.DigestMD5(inData);

// We cannot display binary data, so convert it
// to Base64 and display.
textBox1.Text = crypt.EncodeBase64(hash);
}

ตัวอย่างใน VB6, VB.net

Option Explicit
'/******************************************************************************
' *  Copyright (C) 2000 by Robert Hubley.                                      *
' *  All rights reserved.                                                      *
' *                                                                            *
' *  This software is provided ``AS IS'' and any express or implied            *
' *  warranties, including, but not limited to, the implied warranties of      *
' *  merchantability and fitness for a particular purpose, are disclaimed.     *
' *  In no event shall the authors be liable for any direct, indirect,         *
' *  incidental, special, exemplary, or consequential damages (including, but  *
' *  not limited to, procurement of substitute goods or services; loss of use, *
' *  data, or profits; or business interruption) however caused and on any     *
' *  theory of liability, whether in contract, strict liability, or tort       *
' *  (including negligence or otherwise) arising in any way out of the use of  *
' *  this software, even if advised of the possibility of such damage.         *
' *                                                                            *
' ******************************************************************************
'
'  Form: TestSuite
'
'  DESCRIPTION:
'   A short demonstration form which calls the MD5.DLL library using a
'   standard test suite of values.  The results are displayed next to the
'   expected return set for comparison.
'
'  AUTHOR:
'     Robert M. Hubley 12/1999
'
'
'  NOTES:
'
'
'  CHANGE HISTORY:
'
'     1.0.0  RMH    2000/1/5      Original version
'
'

‘= Global Variables
Dim md5Test As MD5

Private Sub btnRunTest_Click()
    lblResults(0).Caption = LCase(md5Test.DigestStrToHexStr(“”))
    lblResults(1).Caption = LCase(md5Test.DigestStrToHexStr(“a”))
    lblResults(2).Caption = LCase(md5Test.DigestStrToHexStr(“abc”))
    lblResults(3).Caption = LCase(md5Test.DigestStrToHexStr(“message digest”))
    lblResults(4).Caption = LCase(md5Test.DigestStrToHexStr(“abcdefghijklmnopqrstuvwxyz”))
    lblResults(5).Caption = LCase(md5Test.DigestStrToHexStr(“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789”))
    lblResults(6).Caption = LCase(md5Test.DigestStrToHexStr(“12345678901234567890123456789012345678901234567890123456789012345678901234567890”))
End Sub

Private Sub Form_Load()
    ‘ Instantiate our class
    Set md5Test = New MD5
End Sub

vb.net

Imports System Imports System.Security.Cryptography
Imports System.Text

Module Example

    ‘ Hash an input string and return the hash as
    ‘ a 32 character hexadecimal string.
    Function getMd5Hash(ByVal input As String) As String
        ‘ Create a new instance of the MD5 object.
        Dim md5Hasher As MD5 = MD5.Create()

        ‘ Convert the input string to a byte array and compute the hash.
        Dim data As Byte() = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input))

        ‘ Create a new Stringbuilder to collect the bytes
        ‘ and create a string.
        Dim sBuilder As New StringBuilder()

        ‘ Loop through each byte of the hashed data
        ‘ and format each one as a hexadecimal string.
        Dim i As Integer
        For i = 0 To data.Length – 1
            sBuilder.Append(data(i).ToString(“x2”))
        Next i

        ‘ Return the hexadecimal string.
        Return sBuilder.ToString()

    End Function

    ‘ Verify a hash against a string.
    Function verifyMd5Hash(ByVal input As String, ByVal hash As String) As Boolean
        ‘ Hash the input.
        Dim hashOfInput As String = getMd5Hash(input)

        ‘ Create a StringComparer an compare the hashes.
        Dim comparer As StringComparer = StringComparer.OrdinalIgnoreCase

        If 0 = comparer.Compare(hashOfInput, hash) Then
            Return True
        Else
            Return False
        End If

    End Function

    Sub Main()
        Dim source As String = “Hello World!”

        Dim hash As String = getMd5Hash(source)

        Console.WriteLine(“The MD5 hash of ” + source + ” is: ” + hash + “.”)

        Console.WriteLine(“Verifying the hash…”)

        If verifyMd5Hash(source, hash) Then
            Console.WriteLine(“The hashes are the same.”)
        Else
            Console.WriteLine(“The hashes are not same.”)
        End If

    End Sub
End Module
‘ This code example produces the following output:

‘ The MD5 hash of Hello World! is: ed076287532e86365e841e92bfc50d8c.
‘ Verifying the hash…
‘ The hashes are the same.

ตัวอย่างใน Java

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
 
public class AeSimpleMD5 {
 
    private static String convertToHex(byte[] data) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < data.length; i++) {
            int halfbyte = (data[i] >>> 4) & 0x0F;
            int two_halfs = 0;
            do {
                if ((0 <= halfbyte) && (halfbyte <= 9))
                    buf.append((char) (‘0’ + halfbyte));
                else
                    buf.append((char) (‘a’ + (halfbyte – 10)));
                halfbyte = data[i] & 0x0F;
            } while(two_halfs++ < 1);
        }
        return buf.toString();
    }
 
    public static String MD5(String text)
    throws NoSuchAlgorithmException, UnsupportedEncodingException  {
        MessageDigest md;
        md = MessageDigest.getInstance(“MD5”);
        byte[] md5hash = new byte[32];
        md.update(text.getBytes(“iso-8859-1”), 0, text.length());
        md5hash = md.digest();
        return convertToHex(md5hash);
    }
}

แล้วจะนำการเข้ารหัสแบบ MD5 หรือแบบอื่นมาเสนออีก เพื่อเพิ่มความรู้

 

หมวดหมู่:คุย Linux
  1. ยังไม่มีความเห็น
  1. No trackbacks yet.

ใส่ความเห็น

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / เปลี่ยนแปลง )

Twitter picture

You are commenting using your Twitter account. Log Out / เปลี่ยนแปลง )

Facebook photo

You are commenting using your Facebook account. Log Out / เปลี่ยนแปลง )

Google+ photo

You are commenting using your Google+ account. Log Out / เปลี่ยนแปลง )

Connecting to %s

%d bloggers like this: