One Way Hash Function

 

One-way hash function, H(M) beroperasi pada pesan M dengan panjang bebas, dan keluaran fungsi tersebut adalah hash-value h dengan panjang tetap.

h = H(M) , dimana h memiliki panjang m

Karakteristik yang harus dimiliki oleh One-way hash function agar fungsi tersebut menjadi satu arah

  • Diberikan M, sehingga mudah untuk menghitung h
  • Diberikan h, akan sangat sulit menemukan M sehingga H(M) = h
  • Diberikan M, akan sangat sulit untuk menemukan pesan lain M’ , sehingga H(M) = H(M’)

Serangan terhadap One Way Hash Function

  • Serangan pertama, Diberikan hash dari pesan H(M) maka kita dapat membuat pesan lain M’ , sehingga H(M) = H(M’)
  • Serangan kedua, Dapat ditemukan dua pesan random sehingga H(M) = H(M’)

 

SHA 1

 

Fungsi hash SHA merupakan sekumpulan fungsi hash didesain oleh National Security Agency dan dipublikasikan oleh NIST sebagai U.S Federal Information Processing Standard (FIPS). SHA merupakan singkatan dari Secure Hash Algorithm. SHS (Secure Hash Standard) merupakan standar yang mendefinisikan SHA. Ada banyak versi SHA. SHA-0, SHA-1, SHA-2. Sedangkan untuk SHA-2 terbagi lagi menjadi SHA-224, SHA-256, SHA-384, and SHA-512. Di sini hanya akan dibahas mengenai SHA-1. SHA-1 menghasilkan 160 bit message diggest dari pesan yang panjangnya kurang dari 264 bit. SHA-1 hampir mirip dengan MD4 tetapi dengan beberapa perubahan.

Langkah-langkah dalam menghitung nilai hash adalah sebagai berikut :

  1. Message Padding

SHA-1 digunakan untuk menghitung message diggest dari pesan atau file data yang disediakan sebagai input. Pesan atau file dianggap sebagai kumpulan bit-bit. Panjang dari pesan adalah banyaknya bit didalam pesan (Pesan kosong memiliki panjang 0). Jika banyaknya bit di dalam pesan merupakan kelipatan 8, untuk memudahkan pembacaan dapat ditampilkan dalam format hexadecimal.

Tujuan dari message padding adalah membuat panjang total dari isi pesan menjadi kelipatan 512 bit. SHA-1 secara sekuensial memproses blok 512 bit ketika menghitung message diggest.

clip_image004

 

 

Pada message padding, tambahkan satu buah “1” , diikuti oleh m buah “0” diikuti oleh 64 bit integer pada akhir pesan untuk menghasilkan pesan dengan panjang 512 * n. 64 bit integer tersebut adalah panjang dari pesan asli sebelum message padding.

Misalkan pesan dengan panjang L < 26. Sebelum pesan menjadi input SHA-1, dilakukan message padding sebagai berikut

Misal pesan aslinya (L = 40) adalah :

01100001 01100010 01100011 01100100 01100101 (biner)

61 62 63 64 65 (hex)

Tambahkan “1” pada akhir pesan

01100001 01100010 01100011 01100100 01100101 1

Karena L = 40, maka hasilnya menjadi = 41, sehingga diperlukan “0” sebanyak

448 – 41 = 407 buah.

01100001 01100010 01100011 01100100 01100101 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

Dalam hexadecimal hasilnya adalah

61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

Tambahkan 64 bit representasi dari panjang pesan asli. Untuk L = 40, maka representasi dari 64 bit panjang pesan adalah

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00101000 (biner)

00000000 00000028 (hexa)

Maka, setelah ditambahkan hasilnya :

(dalam biner)

01100001 01100010 01100011 01100100 01100101 10000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000

00000000 00000000 00000000 00000000 00000000 00000000 00000000 00101000

(dalam hexa)

61626364 65800000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000028

Hasil dari message padding adalah n 512-bit block (n * 16 word) , untuk suatu n > 0.

Padded message disimbolkan dengan M(1), M(2), …, M(n)

  1. Fungsi dan Konstanta yang Digunakan

Serentetan fungsi logic f(0), f(1), f(2), .. ,f(79) digunakan dalam SHA-1. Setiap f(t) , 0 ≤ t ≤ 79 beroperasi pada 32bit word B, C, D dan menghasilkan 32bit word sebagai output.

f( t; B,C,D) didefinisikan sebagai berikut. Untuk word B,C,D :

f(t;B,C,D) = (B AND C) OR ((NOT B) AND D) ( 0 <= t <= 19)

f(t;B,C,D) = B XOR C XOR D (20 <= t <= 39)

f(t;B,C,D) = (B AND C) OR (B AND D) OR (C AND D) (40 <= t <= 59)

f(t;B,C,D) = B XOR C XOR D (60 <= t <= 79)

Serentetan konstanta K(0), K(1), K(2), … , K(79) digunakan dalam SHA-1.

Dalam hexadecimal konstanta tersebut adalah :

K(t) = 5A827999 ( 0 <= t <= 19)

K(t) = 6ED9EBA1 (20 <= t <= 39)

K(t) = 8F1BBCDC (40 <= t <= 59)

K(t) = CA62C1D6 (60 <= t <= 79)

Selain itu juga digunakan fungsi Circular Left Shift. Circular left shift S^n(X) , dimana X adalah 32 bit word dan n adalah bilangan integer dengan 0 ≤ n < 32.

S^n(X) = (X << n) OR (X >> 32-n)

Contoh: Misalkan X = 11010000 01010000 11100000 00001010 , dan n = 5

Maka

X << 5 = 00001010 00011100 00000001 01000000

X >> 27 = 00000000 00000000 00000000 00011010

————————————————————— (OR)

S^5(X) = 00001010 00011100 00000001 01011010

  1. Menghitung Message Diggest

Message diggest dihitung menggunakan hasil message padding. Komputasi menggunakan dua jenis buffer, setiap jenis buffer tediri dari 5 buah 32-bit word. 5 buah 32-bit word buffer pertama dilabeli dengan A, B, C, D, E. Sedangkan buffer kedua dilabeli H0, H1, H2, H3, H4. Terdapat sebuah sekuen 80 word 32-bit, yang dilabeli W(0), W(1), W(2), …, W(79) dan juga sebuah word buffer yang dilabeli dengan TEMP. Untuk men-generate message diggest, block-block 16 word M(1) M(2) M(3) … M(n) hasil message diggest diproses secara berurutan. Setiap pemrosesan M(i) membutuhkan 80 langkah.

Sebelum memproses apapun, untuk pertama kali, H diinisialisasi sebagai berikut:

H0 = 67452301

H1 = EFCDAB89

H2 = 98BADCFE

H3 = 10325476

H4 = C3D2E1F0

Selanjutnya lakukan komputasi dari M(1), M(2), … , M(n). Untuk setiap M(i), lakukan langkah langkah sebagai berikut ini :

Step 1

Divide M(i) into 16 words W(0), W(1), … , W(15), where W(0) is the left-most word.

Step 2

For t = 16 to 79 do

W(t) = S^1( W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16) )

Step 3

Let A = H0, B = H1, C = H2, D = H3, E = H4

Step 4

For t = 0 to 79 do

TEMP = S^5(A) + f(t;B,C,D) + E + W(t) + K(t);

E = D;

D = C;

C = S^30(B);

B = A;

A = TEMP;

Step 5

H0 = H0 + A;

H1 = H1 + B;

H2 = H2 + C;

H3 = H3 + D;

H4 = H4 + E;

Setelah memproses M(n), message diggest adalah 160-bit string yang direpresentasikan oleh 5 word

H0 H1 H2 H3 H4

Screenshot Program

 

 
  
clip_image007

 
 
clip_image009

Source Code Program

 

File : SHA1.cs (Berisi Class SHA1)

 

 

using System;

 

using System.Collections.Generic;

 

using System.Text;

 

namespace IlkompSHA1

{

 

public class SHA1

{

 

// private

private uint f( int t, uint B, uint C, uint D )

 

{

 

if(t >= 0 && t <= 19)

 

{

 

return (B & C) | ((~B) & D);

 

}

 

else if (t >= 20 && t <= 39)

 

{

 

return (B ^ C ^ D);

 

}

 

else if (t >= 40 && t <= 59)

 

{

 

return (B & C) | (B & D) | (C & D);

 

}

 

else

{

 

return (B ^ C ^ D);

 

}

 

}

 

private uint K( int t )

 

{

 

if (t >= 0 && t <= 19)

 

{

 

return 0x5A827999 ;

 

}

 

else if (t >= 20 && t <= 39)

 

{

 

return 0x6ED9EBA1;

 

}

 

else if (t >= 40 && t <= 59)

 

{

 

return 0x8F1BBCDC;

 

}

 

else

{

 

return 0xCA62C1D6;

 

}

 

}

 

private void ProcessMessageBlock()

 

{

 

int t; // Loop counter

uint temp; // Temporary word value

uint[] W = new uint[80]; // Word sequence

uint A, B, C, D, E; // Word buffers

for (t = 0; t < 16; t++)

 

{

 

W[t] = ((uint)Message_Block[t * 4]) << 24;

 

W[t] |= ((uint)Message_Block[t * 4 + 1]) << 16;

 

W[t] |= ((uint)Message_Block[t * 4 + 2]) << 8;

 

W[t] |= ((uint)Message_Block[t * 4 + 3]);

 

}

 

for (t = 16; t < 80; t++)

 

{

 

W[t] = CircularShift(1, W[t3] ^ W[t8] ^ W[t14] ^ W[t16]);

 

}

 

A = H[0];

 

B = H[1];

 

C = H[2];

 

D = H[3];

 

E = H[4];

 

for (t = 0; t < 80; t++)

 

{

 

temp = CircularShift(5, A) + f(t,B,C,D) + E + W[t] + K(t);

 

E = D;

 

D = C;

 

C = CircularShift(30, B);

 

B = A;

 

A = temp;

 

}

 

 

H[0] = (H[0] + A) ;

 

H[1] = (H[1] + B) ;

 

H[2] = (H[2] + C) ;

 

H[3] = (H[3] + D) ;

 

H[4] = (H[4] + E) ;

 

Message_Block_Index = 0;

 

}

 

private void PadMessage()

 

{

 

if (Message_Block_Index > 55)

 

{

 

Message_Block[Message_Block_Index++] = 0x80;

 

while (Message_Block_Index < 64)

 

{

 

Message_Block[Message_Block_Index++] = 0;

 

}

 

ProcessMessageBlock();

 

while (Message_Block_Index < 56)

 

{

 

Message_Block[Message_Block_Index++] = 0;

 

}

 

}

 

else

 

{

 

Message_Block[Message_Block_Index++] = 0x80;

 

while (Message_Block_Index < 56)

 

{

 

Message_Block[Message_Block_Index++] = 0;

 

}

 

}

 

Message_Block[56] = (byte)((Length_High >> 24) );

 

Message_Block[57] = (byte)((Length_High >> 16) );

 

Message_Block[58] = (byte)((Length_High >> 8) );

 

Message_Block[59] = (byte)((Length_High) );

 

Message_Block[60] = (byte)((Length_Low >> 24) );

 

Message_Block[61] = (byte)((Length_Low >> 16) );

 

Message_Block[62] = (byte)((Length_Low >> 8) );

 

Message_Block[63] = (byte)((Length_Low) );

 

ProcessMessageBlock();

 

}

 

// Performs a circular left shift operation

private UInt32 CircularShift(int bits, UInt32 word)

 

{

 

return (word << bits) | (word >> (32 bits));

 

}

 

private UInt32[] H = new UInt32[5]; // Message digest buffers

private UInt32 Length_Low; // Message length in bits

private UInt32 Length_High; // Message length in bits

private byte[] Message_Block = new byte[64] // 512-bit message blocks

private int Message_Block_Index; // Index into message block array

private bool Computed; // Is the digest computed?

private bool Corrupted; // Is the message digest corruped?

public SHA1()

 

{

 

this.Reset();

 

}

 

public void Reset()

 

{

 

Length_Low = 0;

 

Length_High = 0;

 

Message_Block_Index = 0;

 

H[0] = 0x67452301;

 

H[1] = 0xEFCDAB89;

 

H[2] = 0x98BADCFE;

 

H[3] = 0x10325476;

 

H[4] = 0xC3D2E1F0;

 

Computed = false;

 

Corrupted = false;

 

}

 

public bool Result(ref UInt32[] message_digest_array)

 

{

 

int i; // Counter

if (Corrupted)

 

{

 

return false;

 

}

 

if (!Computed)

 

{

 

PadMessage();

 

Computed = true;

 

}

 

for (i = 0; i < 5; i++)

 

{

 

message_digest_array[i] = H[i];

 

}

 

return true;

 

}

 

public void Input(Byte[] message_array, UInt32 length)

 

{

 

if (length <= 0)

 

{

 

return;

 

}

 

if (Computed || Corrupted)

 

{

 

Corrupted = true;

 

return;

 

}

 

int i = 0;

 

int j = 0;

 

while ((length > 0) && !Corrupted)

 

{

 

i = Message_Block_Index++;

 

Message_Block[i] = (byte)(message_array[j] & 0xFF);

 

Length_Low += 8;

 

if (Length_Low == 0)

 

{

 

Length_High++;

 

if (Length_High == 0)

 

{

 

Corrupted = true; // Message is too long

}

 

}

 

if (Message_Block_Index == 64)

 

{

 

ProcessMessageBlock();

 

}

 

j = j + 1;

 

length = length 1;

 

}

 

}

 

public void Input(byte message_element)

 

{

 

byte[] tmp = { message_element };

 

Input(tmp, 1);

 

}

 

}

 

}

 

 

File : Form1.cs (Berisi method dari Tampilan GUI ketika di click)

using System;

 

using System.Collections.Generic;

 

using System.ComponentModel;

 

using System.Data;

 

using System.Drawing;

 

using System.Text;

 

using System.Windows.Forms;

 

using Microsoft.VisualBasic;

 

// created by BayuPRN

namespace IlkompSHA1

{

 

public partial class MainForm : Form

{

 

public MainForm()

 

{

 

InitializeComponent();

 

}

 

private void bFile_Click(object sender, EventArgs e)

 

{

 

DialogResult d = OpenDialog.ShowDialog();

 

if (d == DialogResult.OK || d == DialogResult.Yes)

 

{

 

String fn = OpenDialog.FileName;

 

MyFileIO fio = new MyFileIO(fn);

 

if (fio.FileExists())

 

{

 

txtFile.Text = fn;

 

byte[] bindata = new byte[1];

 

fio.LoadFile(ref bindata);

 

SHA1 sha = new SHA1();

 

sha.Reset();

 

int i;

 

for (i = 0; i <= bindata.Length 1; i++)

 

{

 

sha.Input(bindata[i]);

 

}

 

uint[] message_diggest = new uint[5];

 

if (!sha.Result(ref message_diggest))

 

{

 

txtHasil.Text = “File tidak dapat diakses!”;

 

}

 

else

 

{

 

txtHasil.Text = String.Format (“{0}-{1}-{2}-{3}-{4}”,

 

Conversion.Hex(message_diggest[0]),

 

Conversion.Hex(message_diggest[1]),

 

Conversion.Hex(message_diggest[2]),

 

Conversion.Hex(message_diggest[3]),

 

Conversion.Hex(message_diggest[4]));

 

}

 

}

 

else

 

{

 

MessageBox.Show(“File tidak dapat diakses atau file tidak ada.”, “:: SHA1 Error”, MessageBoxButtons.OK);

 

}

 

}

 

}

 

}

 

}

 

File : MyFileIO.cs (Berisi class untuk mengakses/membaca isi file)

using System;

 

using System.Collections.Generic;

 

using System.Text;

 

using System.IO;

 

namespace IlkompSHA1

{

 

public class MyFileIO

{

 

private String fn;

 

public MyFileIO( String fileName )

 

{

 

fn = fileName;

 

}

 

public bool FileExists()

 

{

 

if(File.Exists(fn)){

 

return true;

 

} else {

 

return false;

 

}

 

}

 

public bool LoadFile(ref byte[] BinData)

 

{

 

FileStream fs;

 

try

 

{

 

fs = new FileStream( fn, FileMode.Open );

 

BinData = new byte[fs.Length ];

 

fs.Read( BinData, 0, (int)fs.Length );

 

fs.Close();

 

return true;

 

}catch(Exception ex){

 

return false;

 

}

 

}

 

}

 

}

 

 

 

 

 

 

Keterangan

 

Program dibuat menggunakan bahasa C#.NET dan dikompilasi menggunakan .NET Framework v.2.0. Untuk menjalankan program minimal Microsoft .NET Famework versi 2.0 (Windows) atau Mono versi 2.4 (Linux) sudah terinstall di komputer.

Untuk menjalankan program di Windows, jalankan IlkompSHA1.exe

Untuk menjalankan di linux, melalui console jalankan perintah

$> mono IlkompSHA1.exe

Jika ingin mengkompilasi ulang source code di Windows, ketikkan

$> msbuild IlkompSHA1.sln

Jika ingin mengkompilasi ulang source code di Linux, ketikkan

$> xbuild IlkompSHA1.sln

 

 



2 responses to “Penerapan Algoritma HASH SHA1 menggunakan C# .NET”

Leave a Reply

Your email address will not be published. Required fields are marked *

Search

Welcome

Bayu Pratama R N is a lonely programmer who is very enthusiastic about .NET. He just try to live a life of a programmer life and write a blog post when he is so sick about love.

Gallery