def DecryptECIES(curve_name, R, enc, t, pwd): '''Performs ECIES decryption.''' # Setup for Decryption E = PredefinedCurves(curve_name) # Get secret key s hashpwd = SHA512.new(pwd).hexdigest() + RIPEMD.new(pwd).hexdigest() s = int(str(int(hashpwd,16))[0: len(str(E.N))]) % E.N if s < 2: s = E.N/2 # Begin Decryption Z = E.multPoint(s,R) RZ = str(R)+str(Z) H1 = SHA512.new(RZ).hexdigest() k1 = H1[0:32] k2 = H1[32:128] H2 = RIPEMD.new(enc+k2).digest() # If the hashes don't match, stop if base64.b64decode(t) != H2: return "Error: Hashes don't match! Your public key password is most likely incorrect. It is also possible, though improbable, that you selected the wrong encrypted image." cipher = AES.new(k1) message = cipher.decrypt(base64.b64decode(enc)) return message
def PublicKeyECIES(curve_name, pwd, im): '''Create ECIES public key, create the associated binary string, and pass to the image encoder.''' # -------------------------- # ECIES Public Key Creation # -------------------------- E = PredefinedCurves(curve_name) # Generate secret key s via a password hashing. # Use a concatonation of two hash functions to make sure we have enough characters to get a full strength secret key. # For full strenth we need: number of digits of integer version of hash >= numbber of digits of the prime we're working over. hashpwd = SHA512.new(pwd).hexdigest() + RIPEMD.new(pwd).hexdigest() # Convert from hex to int, make hashpwd the same length as the order of the point we're using, then take it modulo order. s = int(str(int(hashpwd,16))[0: len(str(E.N))]) % E.N # If s = 0 or s = 1 (very unlikely), we want to use a different value. if s < 2: s = E.N/2 # Use the secret key s to generate the public key. B = E.multPoint(s, E.A) # ------------------------------------------------------------- # Create a binary string from the given public key information # ------------------------------------------------------------- # # Create a binary string with public key info separated by 2's. # End the string with consecutive 2's. # # The information is encoded in the following order: # # 0. Initial check string. # 1. Length of curve name. # 2. x-coordinate of ellipitc curve point B. # 3. y-coordinate of ellipitc curve point B. # 4. Curve name. # ------------------------------------------------------------- # Change curve name to binary, each character separated by a 2. curve_name_bin = '2'.join([bin(ord(ch)).lstrip('0b') for ch in curve_name]) # Initialize our string as "111111" so we have a quick check that our file is valid when decoding. bit_string = '1111112' # Now append on the binary public key information with a '2' separating each entry. # Note: curve_name_bin already ends in 2 so we only need to add one 2 at the final step. bit_string += bin(len(curve_name)).lstrip('0b') + '2' bit_string += bin(B[0]).lstrip('0b') + '2' bit_string += bin(B[1]).lstrip('0b') + '2' bit_string += curve_name_bin + '2' return EncodeImageInfo(bit_string, im)
def EncryptECIES(curve_name, B, msg, im): '''Perform ECIES encryption, create the associated binary string, and pass to the image encoder.''' E = PredefinedCurves(curve_name) # Make sure the length is correct, otherwise add white space. For AES message length must be multiple of 16. while len(msg) % 16 != 0: msg += ' ' # Begin ECIES Encryption. k = random.randint(2, E.N-1) R = E.multPoint(k, E.A) Z = E.multPoint(k, B) RZ = str(R)+str(Z) H1 = SHA512.new() H1.update(RZ) k1 = H1.hexdigest()[0:32] k2 = H1.hexdigest()[32:128] cipher = AES.new(k1) enc = base64.b64encode(cipher.encrypt(msg)) H2 = RIPEMD.new() H2.update(enc+k2) t = base64.b64encode(H2.digest()) # --------------------------------------------------------------- # Create a binary string from the given encrypted msg information # --------------------------------------------------------------- # # Create a binary string with encrypted msg info separated by 2's. # End the string with consecutive 2's. # # The information is encoded in the following order: # # 1. Initial check string. # 2. Length of curve name. # 3. Length of the encrypted message. # 4. x-coordinate of ellipitc curve point R. # 5. y-coordinate of ellipitc curve point R. # 6. t, the authentication hash value # 7. Curve name. # 8. Encrypted message. # --------------------------------------------------------------- # Convert each character in t, curve_name, and enc to binary with 2's separating each character. t_bin = '2'.join([bin(ord(ch)).lstrip('0b') for ch in t]) curve_name_bin = '2'.join([bin(ord(ch)).lstrip('0b') for ch in curve_name]) enc_bin = '2'.join([bin(ord(ch)).lstrip('0b') for ch in enc]) # Initialize our string as "110011" so we have a quick check that our file is valid when decoding. bit_string = "1100112" # Now append on the binary public key information with a "2" separating each entry. bit_string += bin(len(curve_name)).lstrip('0b') + '2' bit_string += bin(len(enc)).lstrip('0b') + '2' bit_string += bin(R[0]).lstrip('0b') + '2' bit_string += bin(R[1]).lstrip('0b') + '2' bit_string += t_bin + '2' bit_string += curve_name_bin + '2' bit_string += enc_bin + '22' return EncodeImageInfo(bit_string, im)