foreaser 님의 블로그
SHA-1 Algorithm in python 본문






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 추가.