RC4 decryption in python hexadecimal inputs - python
I have a program that successfully encrypts a piece of plain text information and outputs the encrypted data as hexadecimal. i can decrypt this data on http://www.fyneworks.com/encryption/rc4-encryption/index.asp by putting in the hex data i received from my program and the key i used (in plain text)
the next step i am trying to accomplish is to have two inputs where i can input an encrypted message in hex and the encryption key (also in hex).
i'm having trouble getting the decryption part of my program to work...
If i enter the key as password and the ciphertext as 8c905b7c294a94c30422d81d552e which successfully decrypts on the website above... it doesn't work.
anyone have any ideas how i can get decryption working in RC4 with hexadecimal inputs?
# Global variables
state = [None] * 256
p = q = None
def setKey(key):
##RC4 Key Scheduling Algorithm (KSA)
global p, q, state
state = [n for n in range(256)]
p = q = j = 0
for i in range(256):
if len(key) > 0:
j = (j + state[i] + key[i % len(key)]) % 256
else:
j = (j + state[i]) % 256
state[i], state[j] = state[j], state[i]
def byteGenerator():
##RC4 Pseudo-Random Generation Algorithm (PRGA)
global p, q, state
p = (p + 1) % 256
q = (q + state[p]) % 256
state[p], state[q] = state[q], state[p]
return state[(state[p] + state[q]) % 256]
def encrypt(key,inputString):
##Encrypt input string returning a byte list
setKey(string_to_list(key))
return [ord(p) ^ byteGenerator() for p in inputString]
def decrypt(inputByteList):
##Decrypt input byte list returning a string
return "".join([chr(c ^ byteGenerator()) for c in inputByteList])
def intToList(inputNumber):
##Convert a number into a byte list
inputString = "{:02x}".format(inputNumber)
return [int(inputString[i:i + 2], 16) for i in range(0, len(inputString), 2)]
def string_to_list(inputString):
##Convert a string into a byte list
return [ord(c) for c in inputString]
key = raw_input("Enter Key: ")
ciphertext = raw_input("enter ciphertext: ")
print decrypt(intToList(ciphertext))
Here is general idea of how encryption / decryption can be done using reference implementation of RC4 for python:
def KSA(key):
keylength = len(key)
S = range(256)
j = 0
for i in range(256):
j = (j + S[i] + key[i % keylength]) % 256
S[i], S[j] = S[j], S[i] # swap
return S
def PRGA(S):
i = 0
j = 0
while True:
i = (i + 1) % 256
j = (j + S[i]) % 256
S[i], S[j] = S[j], S[i] # swap
K = S[(S[i] + S[j]) % 256]
yield K
def RC4(key):
S = KSA(key)
return PRGA(S)
if __name__ == '__main__':
# ciphertext should be 9D5AB375EC
key = 'secret'
plaintext = 'plain'
def convert_key(s):
return [ord(c) for c in s]
key = convert_key(key)
keystream = RC4(key)
ciphertext = ''.join([("%02X" % (ord(c) ^ keystream.next())) for c in plaintext])
print ciphertext
keystream = RC4(key)
def convert_ct(s):
import binascii
return [ord(ch) for ch in binascii.unhexlify(s)]
ciphertext = convert_ct(ciphertext)
plaintext = ''.join([chr(c ^ keystream.next()) for c in ciphertext])
print plaintext
With your code base it can be done like so:
import binascii
# Global variables
state = [None] * 256
p = q = None
def setKey(key):
##RC4 Key Scheduling Algorithm (KSA)
global p, q, state
state = [n for n in range(256)]
p = q = j = 0
for i in range(256):
if len(key) > 0:
j = (j + state[i] + key[i % len(key)]) % 256
else:
j = (j + state[i]) % 256
state[i], state[j] = state[j], state[i]
def byteGenerator():
##RC4 Pseudo-Random Generation Algorithm (PRGA)
global p, q, state
p = (p + 1) % 256
q = (q + state[p]) % 256
state[p], state[q] = state[q], state[p]
return state[(state[p] + state[q]) % 256]
def encrypt(key, plaintext):
##Encrypt input string returning a byte list
pt = string_to_list(plaintext)
ct = rc4(key, pt)
return list_to_string(ct, hex=True)
def decrypt(key, ciphertext):
##Decrypt input byte list returning a string
ct = string_to_list(ciphertext, hex=True)
pt = rc4(key, ct)
return list_to_string(pt, hex=False)
def string_to_list(input_srt, hex=False):
##Convert a string into an int list
if hex:
res = [ord(ch) for ch in binascii.unhexlify(input_srt)]
else:
res = [ord(ch) for ch in input_srt]
return res
def list_to_string(lst, hex=True):
##Convert an int list into a string
if hex:
res = ''.join(["%0.2X" % el for el in lst])
else:
res = ''.join([chr(el) for el in lst])
return res
def rc4(key, ints):
"""Xor list of ints with output generated by RC4. Output list of ints"""
setKey(string_to_list(key))
return [x ^ byteGenerator() for x in ints]
# key = raw_input("Enter Key: ")
# ciphertext = raw_input("enter ciphertext: ")
key = 'secret'
plaintext = 'plain'
ciphertext = encrypt(key, plaintext)
print ciphertext
print decrypt(key, ciphertext)
Decryption and encryption are basically the same procedures
Related
How to implement HMAC in python without using the hmac library?
I want to implement the hmac algorithm with SHA-1 by the definition from RFC 2104. The code is running but the results aren't the same as the test-vectors from RFC. I'm not sure if I'm loading the values correctly(String to Hex, or String to Bytes?). As template I've used the pseudo-code from wikipedia I'm not sure about the terms 'blocksize' and 'output size'. In the code from wikipedia the outputsize is one of the input values but never used. This is my code so far: First I'm setting up a hash-function, then I'm converting my input-strings (key and message) into hex values. Next step is to to look if key hast go get hashed or filled with zeros. Next I'm xor-ing the single chars from the key with those values (I don't know where they come from, but they're in every example without any comment). Last but not least I'm combining an inner string(I_key_pad + message) and hash it which results in an outer strings that im combining with the outer pad and hash it again. import hashlib from functools import reduce def hmac(key, message, hashfunc): hasher = hashlib.sha1 blocksize = 40 message = toHex(message) #is this right? key = toHex(key) #alternative: loading values as bytes #message = bytes(message, 'utf-8') #key = bytes(key, 'utf-8') if len(key) > blocksize: key = hasher(key) else: #key = key.ljust(blocksize, '0') #filling from right to left #key = key.ljust(blocksize, b'\0') #same as above but for bytes key = pad(key, blocksize) #filling from left to right val1 = 0x5c val2 = 0x36 i = 0 o_key_pad = "" i_key_pad = "" while i < blocksize: o_key_pad += str(ord(key[i]) ^ val1) i_key_pad += str(ord(key[i]) ^ val2) i += 1 tmp_string = str(i_key_pad) + str(message) tmp_string = tmp_string.encode() inner_hash = hasher(tmp_string).hexdigest() fullstring = str(o_key_pad) + inner_hash fullstring = fullstring.encode() fullstring = hasher(fullstring).hexdigest() print(fullstring) def pad(key, blocksize): key = str(key) while len(key) < blocksize: key = '0' + key key = key return key def toHex(s): lst = [] for ch in s: hv = hex(ord(ch)).replace('0x', '') if len(hv) == 1: hv = '0' + hv lst.append(hv) return reduce(lambda x, y: x + y, lst) def main(): while (1): key = input("key = ") message = input("message = ") hash = input("hash (0: SHA-256, 1: SHA-1) = ") hmac(key, message, hash) if __name__ == "__main__": main()
I'm not understanding all the steps in your code, but here's a short example showing HMAC-SHA1 using only hashlib.sha1, with a helper function xor. import hashlib def xor(x, y): return bytes(x[i] ^ y[i] for i in range(min(len(x), len(y)))) def hmac_sha1(key_K, data): if len(key_K) > 64: raise ValueError('The key must be <= 64 bytes in length') padded_K = key_K + b'\x00' * (64 - len(key_K)) ipad = b'\x36' * 64 opad = b'\x5c' * 64 h_inner = hashlib.sha1(xor(padded_K, ipad)) h_inner.update(data) h_outer = hashlib.sha1(xor(padded_K, opad)) h_outer.update(h_inner.digest()) return h_outer.digest() def do_tests(): # test 1 k = b'\x0b' * 20 data = b"Hi There" result = hmac_sha1(k, data) print(result.hex()) # add tests as desired
SHA256 doesn't yield same result
I'm following on this tutorial and in part 2 (picture below) it shows that the SHA256 yields a result different than what I get when I ran my python code: the string is: 0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6 While the tutorial SHA256 comes to: 600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408 My short python shows: sha_result = sha256(bitconin_addresss).hexdigest().upper() print sha_result 32511E82D56DCEA68EB774094E25BAB0F8BDD9BC1ECA1CEEDA38C7A43ACEDDCE in fact, any online sha256 shows the same python result; so am I missing here something?
You're hashing the string when you're supposed to be hashing the bytes represented by that string. >>> hashlib.sha256('0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'.decode('hex')).hexdigest().upper() '600FFE422B4E00731A59557A5CCA46CC183944191006324A447BDB2D98D4B408'
You could use Gavin's "base58.py", which I believe he no longer shares it on his github page. However you probably could easily google and find different versions of it from github. Here is one version edited a little by me: #!/usr/bin/env python """encode/decode base58 in the same way that Bitcoin does""" import math import sys __b58chars = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' __b58base = len(__b58chars) def b58encode(v): """ encode v, which is a string of bytes, to base58. """ long_value = 0L for (i, c) in enumerate(v[::-1]): long_value += ord(c) << (8*i) # 2x speedup vs. exponentiation result = '' while long_value >= __b58base: div, mod = divmod(long_value, __b58base) result = __b58chars[mod] + result long_value = div result = __b58chars[long_value] + result # Bitcoin does a little leading-zero-compression: # leading 0-bytes in the input become leading-1s nPad = 0 for c in v: if c == '\0': nPad += 1 else: break return (__b58chars[0]*nPad) + result def b58decode(v): """ decode v into a string of len bytes """ long_value = 0L for (i, c) in enumerate(v[::-1]): long_value += __b58chars.find(c) * (__b58base**i) result = '' while long_value >= 256: div, mod = divmod(long_value, 256) result = chr(mod) + result long_value = div result = chr(long_value) + result nPad = 0 for c in v: if c == __b58chars[0]: nPad += 1 else: break result = chr(0)*nPad + result return result try: import hashlib hashlib.new('ripemd160') have_crypto = True except ImportError: have_crypto = False def hash_160(public_key): if not have_crypto: return '' h1 = hashlib.sha256(public_key).digest() r160 = hashlib.new('ripemd160') r160.update(h1) h2 = r160.digest() return h2 def hash_160_to_bc_address(h160, version="\x00"): if not have_crypto: return '' vh160 = version+h160 h3=hashlib.sha256(hashlib.sha256(vh160).digest()).digest() addr=vh160+h3[0:4] return b58encode(addr) def public_key_to_bc_address(public_key, version="\x00"): if not have_crypto or public_key is None: return '' h160 = hash_160(public_key) return hash_160_to_bc_address(h160, version=version) def sec_to_bc_key(sec, version="\x80"): if not have_crypto or sec is None: return '' vsec = version+sec +"\x01" hvsec=hashlib.sha256(hashlib.sha256(vsec).digest()).digest() return b58encode(vsec+hvsec[0:4]) def bc_key_to_sec(prv): return b58decode(prv)[1:33] def bc_address_to_hash_160(addr): bytes = b58decode(addr) return bytes[1:21] if __name__ == '__main__': if len(sys.argv) > 1: if sys.argv[1] == '-en': print b58encode(sys.argv[2].decode('hex_codec')) if sys.argv[1] == '-de': print b58decode(sys.argv[2]).encode('hex_codec') if sys.argv[1] == '-pub': print public_key_to_bc_address(sys.argv[2].decode('hex_codec')) if sys.argv[1] == '-adr': print bc_address_to_hash_160(sys.argv[2]).encode('hex_codec') if sys.argv[1] == '-sec': print sec_to_bc_key(sys.argv[2].decode('hex_codec')) if sys.argv[1] == '-prv': print bc_key_to_sec(sys.argv[2]).encode('hex_codec') else: print '' print 'Usage: ./base58.py [options]' print '' print ' -en converts hex to base58' print ' -de converts base58 to hex' print print ' -pub public_key_to_bc_address' print ' -adr bc_address_to_hash_160' print print ' -sec sec_to_bc_key' print ' -prv bc_key_to_sec' print To answer your specific question, based on above code you could use this command: hashlib.sha256('0450863AD64A87AE8A2FE83C1AF1A8403CB53F53E486D8511DAD8A04887E5B23522CD470243453A299FA9E77237716103ABC11A1DF38855ED6F2EE187E9C582BA6'.decode('hex_codec')).digest().encode('hex_codec').upper()
Rsa cipher error
I wrote the following code in python 3.4 import sys DEFAULT_BLOCK_SIZE = 128 BYTE_SIZE = 256 def main(): filename = 'encrypted_file.txt' mode = 'encrypt' if mode == 'encrypt': message = '''"Journalists belong in the gutter because that is where the ruling classes throw their guilty secrets." -Gerald Priestland "TheFounding Fathers gave the free press the protection it must have to bare the secrets of government and inform the people." -Hugo Black''' pubKeyFilename = 'vineeth_pubkey.txt' print('Encrypting and writing to %s...' % (filename)) encryptedText = encryptAndWriteToFile(filename, pubKeyFilename, message) print('Encrypted text:') print(encryptedText) elif mode == 'decrypt': privKeyFilename = 'vineeth_privkey.txt' print('Reading from %s and decrypting...' % (filename)) decryptedText = readFromFileAndDecrypt(filename, privKeyFilename) print('Decrypted text:') print(decryptedText) def getBlocksFromText(message, blockSize=DEFAULT_BLOCK_SIZE): messageBytes = message.encode('ascii') blockInts = [] for blockStart in range(0, len(messageBytes), blockSize): blockInt = 0 for i in range(blockStart, min(blockStart + blockSize, len(messageBytes))): blockInt += messageBytes[i] * (BYTE_SIZE ** (i % blockSize)) blockInts.append(blockInt) return blockInts def getTextFromBlocks(blockInts, messageLength,blockSize=DEFAULT_BLOCK_SIZE): message = [] for blockInt in blockInts: blockMessage = [] for i in range(blockSize- 1, -1, -1): if len(message) + i < messageLength: asciiNumber = blockInt // (BYTE_SIZE ** i) blockInt = blockInt % (BYTE_SIZE ** i) blockMessage.insert(0, chr(asciiNumber)) message.extend(blockMessage) return ''.join(message) def encryptMessage(message, key, blockSize=DEFAULT_BLOCK_SIZE): encryptedBlocks = [] n, e = key for block in getBlocksFromText(message, blockSize): encryptedBlocks.append(pow(block, e, n)) return encryptedBlocks def decryptMessage(encryptedBlocks, messageLength, key, blockSize=DEFAULT_BLOCK_SIZE): decryptedBlocks = [] n, d = key for block in encryptedBlocks: decryptedBlocks.append(pow(block, d, n)) return getTextFromBlocks(decryptedBlocks, messageLength, blockSize) def readKeyFile(keyFilename): fo = open(keyFilename) content = fo.read() fo.close() keySize, n, EorD = content.split(',') return (int(keySize), int(n), int(EorD)) def encryptAndWriteToFile(messageFilename, keyFilename, message, blockSize=DEFAULT_BLOCK_SIZE): keySize, n, e = readKeyFile(keyFilename) if keySize < blockSize * 8: print'ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or less than the key size. Either increase the block size or use different keys.' % (blockSize * 8, keySize) sys.exit() encryptedBlocks = encryptMessage(message, (n, e), blockSize) for i in range(len(encryptedBlocks)): encryptedBlocks[i] = str(encryptedBlocks[i]) encryptedContent = ','.join(encryptedBlocks) encryptedContent = '%s_%s_%s' % (len(message), blockSize, encryptedContent) fo = open(messageFilename, 'w') fo.write(encryptedContent) fo.close() return encryptedContent def readFromFileAndDecrypt(messageFilename, keyFilename): keySize, n, d = readKeyFile(keyFilename) fo = open(messageFilename) content = fo.read() messageLength, blockSize, encryptedMessage = content.split('_') messageLength = int(messageLength) blockSize = int(blockSize) if keySize < blockSize * 8: print 'ERROR: Block size is %s bits and key size is %s bits. The RSA cipher requires the block size to be equal to or less than the keysize. Did you specify the correct key file and encrypted file?' % (blockSize * 8, keySize) encryptedBlocks = [] for block in encryptedMessage.split(','): encryptedBlocks.append(int(block)) return decryptMessage(encryptedBlocks, messageLength, (n, d), blockSize) if __name__ == '__main__': main() It generates the following error when used in python 2.7 Traceback (most recent call last): File "E:\Python27\My programs\rsa.py", line 94, in <module> main() File "E:\Python27\My programs\rsa.py", line 11, in main encryptedText = encryptAndWriteToFile(filename, pubKeyFilename, message) File "E:\Python27\My programs\rsa.py", line 69, in encryptAndWriteToFile encryptedBlocks = encryptMessage(message, (n, e), blockSize) File "E:\Python27\My programs\rsa.py", line 46, in encryptMessage for block in getBlocksFromText(message, blockSize): File "E:\Python27\My programs\rsa.py", line 27, in getBlocksFromText blockInt += messageBytes[i] * (BYTE_SIZE ** (i % blockSize)) TypeError: unsupported operand type(s) for +=: 'int' and 'str' Could anyone help in troubleshooting this code so that it works in python 2.7? Thanks! P.S It worked in python 3.4.
Look at the error TypeError: unsupported operand type(s) for +=: 'int' and 'str' It is derived from File "E:\Python27\My programs\rsa.py", line 27, in getBlocksFromText blockInt += messageBytes[i] * (BYTE_SIZE ** (i % blockSize)) You are trying to and operation on a int and a string. You need to convert either of them to the same type numbers = 12345 letters = 'abcde' num_letters = '12345' # this works: str(numbers) int(num_letters) # this doesn't work: int(letters)
SHA-256 implementation in Python
I'm looking for a Python implementation of the SHA-256 hash function. I want to use it to get a better understanding of how the SHA-256 function works, and I think Python is the ideal language for this. Pseudo-code has the limitation that I can't run/test it, to see what my modifications of the code do to the output.
PyPy's source contains a pure-python implementation of SHA-256 here. Poking around in that directory, you'll probably also find pure-python implementations of other standard hashes.
initial_hash_values=[ '6a09e667','bb67ae85','3c6ef372','a54ff53a', '510e527f','9b05688c','1f83d9ab','5be0cd19' ] sha_256_constants=[ '428a2f98','71374491','b5c0fbcf','e9b5dba5', '3956c25b','59f111f1','923f82a4','ab1c5ed5', 'd807aa98','12835b01','243185be','550c7dc3', '72be5d74','80deb1fe','9bdc06a7','c19bf174', 'e49b69c1','efbe4786','0fc19dc6','240ca1cc', '2de92c6f','4a7484aa','5cb0a9dc','76f988da', '983e5152','a831c66d','b00327c8','bf597fc7', 'c6e00bf3','d5a79147','06ca6351','14292967', '27b70a85','2e1b2138','4d2c6dfc','53380d13', '650a7354','766a0abb','81c2c92e','92722c85', 'a2bfe8a1','a81a664b','c24b8b70','c76c51a3', 'd192e819','d6990624','f40e3585','106aa070', '19a4c116','1e376c08','2748774c','34b0bcb5', '391c0cb3','4ed8aa4a','5b9cca4f','682e6ff3', '748f82ee','78a5636f','84c87814','8cc70208', '90befffa','a4506ceb','bef9a3f7','c67178f2' ] def bin_return(dec): return(str(format(dec,'b'))) def bin_8bit(dec): return(str(format(dec,'08b'))) def bin_32bit(dec): return(str(format(dec,'032b'))) def bin_64bit(dec): return(str(format(dec,'064b'))) def hex_return(dec): return(str(format(dec,'x'))) def dec_return_bin(bin_string): return(int(bin_string,2)) def dec_return_hex(hex_string): return(int(hex_string,16)) def L_P(SET,n): to_return=[] j=0 k=n while k<len(SET)+1: to_return.append(SET[j:k]) j=k k+=n return(to_return) def s_l(bit_string): bit_list=[] for i in range(len(bit_string)): bit_list.append(bit_string[i]) return(bit_list) def l_s(bit_list): bit_string='' for i in range(len(bit_list)): bit_string+=bit_list[i] return(bit_string) def rotate_right(bit_string,n): bit_list = s_l(bit_string) count=0 while count <= n-1: list_main=list(bit_list) var_0=list_main.pop(-1) list_main=list([var_0]+list_main) bit_list=list(list_main) count+=1 return(l_s(list_main)) def shift_right(bit_string,n): bit_list=s_l(bit_string) count=0 while count <= n-1: bit_list.pop(-1) count+=1 front_append=['0']*n return(l_s(front_append+bit_list)) def mod_32_addition(input_set): value=0 for i in range(len(input_set)): value+=input_set[i] mod_32 = 4294967296 return(value%mod_32) def xor_2str(bit_string_1,bit_string_2): xor_list=[] for i in range(len(bit_string_1)): if bit_string_1[i]=='0' and bit_string_2[i]=='0': xor_list.append('0') if bit_string_1[i]=='1' and bit_string_2[i]=='1': xor_list.append('0') if bit_string_1[i]=='0' and bit_string_2[i]=='1': xor_list.append('1') if bit_string_1[i]=='1' and bit_string_2[i]=='0': xor_list.append('1') return(l_s(xor_list)) def and_2str(bit_string_1,bit_string_2): and_list=[] for i in range(len(bit_string_1)): if bit_string_1[i]=='1' and bit_string_2[i]=='1': and_list.append('1') else: and_list.append('0') return(l_s(and_list)) def or_2str(bit_string_1,bit_string_2): or_list=[] for i in range(len(bit_string_1)): if bit_string_1[i]=='0' and bit_string_2[i]=='0': or_list.append('0') else: or_list.append('1') return(l_s(or_list)) def not_str(bit_string): not_list=[] for i in range(len(bit_string)): if bit_string[i]=='0': not_list.append('1') else: not_list.append('0') return(l_s(not_list)) ''' SHA-256 Specific Functions: ''' def Ch(x,y,z): return(xor_2str(and_2str(x,y),and_2str(not_str(x),z))) def Maj(x,y,z): return(xor_2str(xor_2str(and_2str(x,y),and_2str(x,z)),and_2str(y,z))) def e_0(x): return(xor_2str(xor_2str(rotate_right(x,2),rotate_right(x,13)),rotate_right(x,22))) def e_1(x): return(xor_2str(xor_2str(rotate_right(x,6),rotate_right(x,11)),rotate_right(x,25))) def s_0(x): return(xor_2str(xor_2str(rotate_right(x,7),rotate_right(x,18)),shift_right(x,3))) def s_1(x): return(xor_2str(xor_2str(rotate_right(x,17),rotate_right(x,19)),shift_right(x,10))) def message_pad(bit_list): pad_one = bit_list + '1' pad_len = len(pad_one) k=0 while ((pad_len+k)-448)%512 != 0: k+=1 back_append_0 = '0'*k back_append_1 = bin_64bit(len(bit_list)) return(pad_one+back_append_0+back_append_1) def message_bit_return(string_input): bit_list=[] for i in range(len(string_input)): bit_list.append(bin_8bit(ord(string_input[i]))) return(l_s(bit_list)) def message_pre_pro(input_string): bit_main = message_bit_return(input_string) return(message_pad(bit_main)) def message_parsing(input_string): return(L_P(message_pre_pro(input_string),32)) def message_schedule(index,w_t): new_word = bin_32bit(mod_32_addition([int(s_1(w_t[index-2]),2),int(w_t[index-7],2),int(s_0(w_t[index-15]),2),int(w_t[index-16],2)])) return(new_word) ''' This example of SHA_256 works for an input string <56 characters. ''' def sha_256(input_string): assert len(input_string) < 56, "This example of SHA_256 works for an input string <56 characters." w_t=message_parsing(input_string) a=bin_32bit(dec_return_hex(initial_hash_values[0])) b=bin_32bit(dec_return_hex(initial_hash_values[1])) c=bin_32bit(dec_return_hex(initial_hash_values[2])) d=bin_32bit(dec_return_hex(initial_hash_values[3])) e=bin_32bit(dec_return_hex(initial_hash_values[4])) f=bin_32bit(dec_return_hex(initial_hash_values[5])) g=bin_32bit(dec_return_hex(initial_hash_values[6])) h=bin_32bit(dec_return_hex(initial_hash_values[7])) for i in range(0,64): if i <= 15: t_1=mod_32_addition([int(h,2),int(e_1(e),2),int(Ch(e,f,g),2),int(sha_256_constants[i],16),int(w_t[i],2)]) t_2=mod_32_addition([int(e_0(a),2),int(Maj(a,b,c),2)]) h=g g=f f=e e=mod_32_addition([int(d,2),t_1]) d=c c=b b=a a=mod_32_addition([t_1,t_2]) a=bin_32bit(a) e=bin_32bit(e) if i > 15: w_t.append(message_schedule(i,w_t)) t_1=mod_32_addition([int(h,2),int(e_1(e),2),int(Ch(e,f,g),2),int(sha_256_constants[i],16),int(w_t[i],2)]) t_2=mod_32_addition([int(e_0(a),2),int(Maj(a,b,c),2)]) h=g g=f f=e e=mod_32_addition([int(d,2),t_1]) d=c c=b b=a a=mod_32_addition([t_1,t_2]) a=bin_32bit(a) e=bin_32bit(e) hash_0 = mod_32_addition([dec_return_hex(initial_hash_values[0]),int(a,2)]) hash_1 = mod_32_addition([dec_return_hex(initial_hash_values[1]),int(b,2)]) hash_2 = mod_32_addition([dec_return_hex(initial_hash_values[2]),int(c,2)]) hash_3 = mod_32_addition([dec_return_hex(initial_hash_values[3]),int(d,2)]) hash_4 = mod_32_addition([dec_return_hex(initial_hash_values[4]),int(e,2)]) hash_5 = mod_32_addition([dec_return_hex(initial_hash_values[5]),int(f,2)]) hash_6 = mod_32_addition([dec_return_hex(initial_hash_values[6]),int(g,2)]) hash_7 = mod_32_addition([dec_return_hex(initial_hash_values[7]),int(h,2)]) final_hash = (hex_return(hash_0), hex_return(hash_1), hex_return(hash_2), hex_return(hash_3), hex_return(hash_4), hex_return(hash_5), hex_return(hash_6), hex_return(hash_7)) return(final_hash)
Some time ago I was also studying SHA-256 and created pure-python class that implements this hash. If I remember correctly, mostly I've taken algorithm from Wikipedia SHA-256 Pseudocode and partially from some open-source projects. Algorithm doesn't import any (even standard) modules. Of cause it is much slower than hashlib's variant and only meant for studying. If you just run the script it executes 1000 tests comparing hashlib's and my variants. Only testing function imports some modules, algorithm's class itself doesn't need any modules. Interface is same as in hashlib's sha256 class. See test() function for examples of usage. Try it online! class Sha256: ks = [ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2, ] hs = [ 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, ] M32 = 0xFFFFFFFF def __init__(self, m = None): self.mlen = 0 self.buf = b'' self.k = self.ks[:] self.h = self.hs[:] self.fin = False if m is not None: self.update(m) #staticmethod def pad(mlen): mdi = mlen & 0x3F length = (mlen << 3).to_bytes(8, 'big') padlen = 55 - mdi if mdi < 56 else 119 - mdi return b'\x80' + b'\x00' * padlen + length #staticmethod def ror(x, y): return ((x >> y) | (x << (32 - y))) & Sha256.M32 #staticmethod def maj(x, y, z): return (x & y) ^ (x & z) ^ (y & z) #staticmethod def ch(x, y, z): return (x & y) ^ ((~x) & z) def compress(self, c): w = [0] * 64 w[0 : 16] = [int.from_bytes(c[i : i + 4], 'big') for i in range(0, len(c), 4)] for i in range(16, 64): s0 = self.ror(w[i - 15], 7) ^ self.ror(w[i - 15], 18) ^ (w[i - 15] >> 3) s1 = self.ror(w[i - 2], 17) ^ self.ror(w[i - 2], 19) ^ (w[i - 2] >> 10) w[i] = (w[i - 16] + s0 + w[i - 7] + s1) & self.M32 a, b, c, d, e, f, g, h = self.h for i in range(64): s0 = self.ror(a, 2) ^ self.ror(a, 13) ^ self.ror(a, 22) t2 = s0 + self.maj(a, b, c) s1 = self.ror(e, 6) ^ self.ror(e, 11) ^ self.ror(e, 25) t1 = h + s1 + self.ch(e, f, g) + self.k[i] + w[i] h = g g = f f = e e = (d + t1) & self.M32 d = c c = b b = a a = (t1 + t2) & self.M32 for i, (x, y) in enumerate(zip(self.h, [a, b, c, d, e, f, g, h])): self.h[i] = (x + y) & self.M32 def update(self, m): if m is None or len(m) == 0: return assert not self.fin, 'Hash already finalized and can not be updated!' self.mlen += len(m) m = self.buf + m for i in range(0, len(m) // 64): self.compress(m[64 * i : 64 * (i + 1)]) self.buf = m[len(m) - (len(m) % 64):] def digest(self): if not self.fin: self.update(self.pad(self.mlen)) self.digest = b''.join(x.to_bytes(4, 'big') for x in self.h[:8]) self.fin = True return self.digest def hexdigest(self): tab = '0123456789abcdef' return ''.join(tab[b >> 4] + tab[b & 0xF] for b in self.digest()) def test(): import secrets, hashlib, random for itest in range(500): data = secrets.token_bytes(random.randrange(257)) a, b = hashlib.sha256(data).hexdigest(), Sha256(data).hexdigest() assert a == b, (a, b) for itest in range(500): a, b = hashlib.sha256(), Sha256() for j in range(random.randrange(10)): data = secrets.token_bytes(random.randrange(129)) a.update(data) b.update(data) a, b = a.hexdigest(), b.hexdigest() assert a == b, (a, b) print('Sha256 tested successfully.') if __name__ == '__main__': test()
If you only want the hash value: from hashlib import sha256 data = input('Enter plaintext data: ') output = sha256(data.encode('utf-8')) print(output) Python's hashlib also has SHA-1, SHA-384, SHA-512, and MD5 hash functions.
Here is my proposition with redis: for i in range(len(rserver.keys())): mdp_hash = rserver.get(rserver.keys()[i]) rserver.set(rserver.keys()[i], hashlib.sha256(mdp_hash.encode()).hexdigest())
Translating http://en.wikipedia.org/wiki/SHA-2#SHA-256_.28a_SHA-2_variant.29_pseudocode to Python should be straight forward.
Custom Python Encryption algorithm
Hey, I have been working on this for a while, and I can remebr my brother stepped me through this very same alogorithm. Basicly, it just adds the ascii values of both the characters from the key, and the phrase. I can encrypt it with this: def encrypt(key, string): encoded = '' for i in range(len(string)): key_c = ord(key[i % len(key)]) string_c = ord(string[i % len(string)]) encoded += chr((key_c + string_c) % 127) return encoded But I can't seem to remember what we did as far as decrypting. Its difficult to revers a mod :P Any ideas?
That's simple, let's see how it works. First of all, the encrypted message is obtained by subtracting the key. enc = msg + key (mod 127) How can we obtain the original message? That's easy, subtract the key in both sides enc - key = msg + key - key (mod 127) And here we get: enc - key = msg (mod 127) For more details, please refer to Modular arithmetic, I think it should belong one of group/field/ring. I'm not an expert in math, for further reading, you should check out Number theory. Here is the refined code: def encrypt(key, msg): encryped = [] for i, c in enumerate(msg): key_c = ord(key[i % len(key)]) msg_c = ord(c) encryped.append(chr((msg_c + key_c) % 127)) return ''.join(encryped) def decrypt(key, encryped): msg = [] for i, c in enumerate(encryped): key_c = ord(key[i % len(key)]) enc_c = ord(c) msg.append(chr((enc_c - key_c) % 127)) return ''.join(msg) if __name__ == '__main__': key = 'This_is_my_awsome_secret_key' msg = 'Hello world' encrypted = encrypt(key, msg) decrypted = decrypt(key, encrypted) print 'Message:', repr(msg) print 'Key:', repr(key) print 'Encrypted:', repr(encrypted) print 'Decrypted:', repr(decrypted) Output Message: 'Hello world' Key: 'This_is_my_awsome_secret_key' Encrypted: '\x1dNV`O\nkO`fD' Decrypted: 'Hello world'
Decryption is the same, except with minus instead of plus.
But you do not need to inverse the mod, just the + key_c, right? So just add 128, subtract key_c, and do modulo 127 again to keep in range. (instead of the last line, all the other lines are the same as with encrypting.