Notice
Recent Posts
Recent Comments
Link
«   2025/07   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
Archives
Today
Total
관리 메뉴

foreaser 님의 블로그

SHA-1 Algorithm in python 본문

카테고리 없음

SHA-1 Algorithm in python

foreaser 2024. 11. 1. 01:36

 

 

 

 

 

 
 
 
 
def block(messageLength, blockSize):
    chunk = []
    for i in range(0, len(messageLength), blockSize):
        chunk.append(messageLength[i:i + blockSize])

    return chunk


def ROTL(W, rotateNumber): # (왼쪽으로 1비트시프트연산) | (오른쪽으로 32 - 1 비트시프트연산)
    return ((W << rotateNumber) | (W >> (32 - rotateNumber))) & 0xffffffff

def sha1(Message):
    # initial hash values
    h0 = 0x67452301
    h1 = 0xEFCDAB89
    h2 = 0x98BADCFE
    h3 = 0x10325476
    h4 = 0xC3D2E1F0

    Binary_Message = ""

    #print("len(message) : %d"%len(Message))

    for char in range(len(Message)):
        Binary_Message += '{0:08b}'.format(ord(Message[char])) #입력받은 문자를 8비트 바이너리로 변환 (a == 97, 01100001) 8비트를 계속 이어 붙임.
        #print("messageLength : " + Binary_Message)

    temp = Binary_Message
    #print("temp"+temp)
    Binary_Message += '1' #이어 붙인 곳에다 1을 추가함
    #print("1messageLength : " + Binary_Message)

    while (len(Binary_Message) % 512 != 448): #512로 나누어서 나머지가 448(512-64)가 될 때 까지 0을 추가함
        Binary_Message += '0'
    #print("448 messageLength : " + Binary_Message)
    Binary_Message += '{0:064b}'.format(len(temp)) # 1을 붙이기 전의 메시지 바이너리데이터를64비트로 만들어서 이어붙임

    #print("64 while messageLength : " + Binary_Message)
    chunk = block(Binary_Message, 512) #이어 붙여진 바이너리메시지를 512비트로 나눔(리스트에 한 요소로 512비트씩 박음) 한 요소에 64바이트

    for eachChunk in chunk:
        words = block(eachChunk, 32) #나눠진 512비트를 다시 32비트(워드)로 나누어서 word 변수에 넣음
        w = [0] * 80 #w라는 리스트의 80개 요소에 각각 0을 대입

        for n in range(0, 16):
            w[n] = int(words[n], 2) #words에 저장된 2진수(,2)를 10진수로(int) 변환하여 w[n]에 저장
            #print("w[%d] : "%n,end='')
            #print(w[n])

        # XOR == ^
        for i in range(16, 80): #W16~W79 비트연산
            w[i] = ROTL((w[i - 3] ^ w[i - 8] ^ w[i - 14] ^ w[i - 16]), 1)
            #print("w[%d]"%(i),end='')
            #print(w[i])

        #print("words : ",end='')
        #print(words)

        a = h0
        b = h1
        c = h2
        d = h3
        e = h4

    # x==b y==c z==d
    # AND == & , XOR == ^ , NOT == ~

        for i in range(0, 80):
            if 0 <= i <= 19:
                f = (b & c) ^ ((~b) & d)
                k = 0x5A827999

            elif 20 <= i <= 39:
                f = b ^ c ^ d
                k = 0x6ED9EBA1

            elif 40 <= i <= 59:
                f = (b & c) ^ (b & d) ^ (c & d)
                k = 0x8F1BBCDC

            elif 60 <= i <= 79:
                f = b ^ c ^ d
                k = 0xCA62C1D6


            T = (ROTL(a, 5) + f + e + k + w[i]) & 0xffffffff
            e = d
            d = c
            c = ROTL(b,30)
            b = a
            a = T


        h0 = (h0 + a) & 0xffffffff
        h1 = (h1 + b) & 0xffffffff
        h2 = (h2 + c) & 0xffffffff
        h3 = (h3 + d) & 0xffffffff
        h4 = (h4 + e) & 0xffffffff

    return ("%08x%08x%08x%08x%08x"% (h0, h1, h2, h3, h4))

while True:
    msg = input("Input : ")
    print("output : ",sha1(msg))

 

 
 

[3]

 

 

 

SHA1 Collision 연구를 진행해야해서 SHA1에 대한 원리를 꼭 알아야만 했다.

원리 공부 겸 NIST 문서와 Youtube영상 등을 참고하며 파이썬으로 SHA1 해싱알고리즘을 구현해보았다.

 

 

 

 

22.05.13 수정내용

h0~h4에서 비트가 오버플로우 될 수 있어 0xffffffff 추가.