I am trying to do a P2MS script.
For my script, I am saving the keys into a text file with DER format instead of the usual PEM file. Both key and signatures are saved in a text file and hexlify. Below is my code for the P2MS execution.
from Crypto.PublicKey import DSA
from Crypto.Hash import SHA256
from Crypto.Signature import DSS
from binascii import hexlify, unhexlify
import binascii
message = b"helpsmepls"
# Read scriptPubKey and scriptSig from files
with open('scriptPubKey.txt', 'r') as f:
readscriptPubKey = f.read().strip()
with open('scriptSig.txt', 'r') as f:
scriptSig = f.read().strip()
print(type(readscriptPubKey))
tempholder = readscriptPubKey.split()
# Removing the first character and last character
removeend = tempholder[1:-1]
scriptPubKey = []
# Removing front extra headings
for count, x in enumerate(removeend):
w = bytes(removeend[count][1:-1], encoding = 'utf-8')
#print(w)
scriptPubKey.append(w)
# Splitting the Signatures
signatures = scriptSig.split()
hash_obj = SHA256.new(message)
# Going through the pubkeys based on the number of signatures generated
for o, sig in enumerate(signatures):
pub_key = DSA.import_key(bytes.fromhex(scriptPubKey[o].decode("utf-8")))
hash_obj = SHA256.new(message)
verifier = DSS.new(pub_key, 'fips-183-3')
# Verifying if the Public key and signatures match, loop will break if False is encountered
if verifier.verify(hash_obj, sig):
d = True
else:
d = False
break
break
if d == True:
print("The message is authentic.")
else: print("The message is not authentic.")
Unfortunately before my code can reach the verification, it encountered an error.
Full traceback
It seems my DSA key format has an error, but I am not too sure why is it giving me that error.
I have also tried unhexlifying my input from the public key text file, but it also did not work. I have tried to hex decode the input to get the DER format of the input, but my type is still just bytes. I am not so sure how to properly import the key with the appropriate DSA key format from a txt file. I am able to do that with a PEM file but would just like to find out how to execute it with a txt file.
My expected outcome is the DSA key is imported properly and i am able to verify the public key with the signatures.
I just tried my hand at encrypting and decrypting data. I first generated a key, then encrypted data with it and saved it to an XML file. Now this data is read and should be decrypted again.
But now I get the error message "cryptography.fernet.InvalidToken".
import xml.etree.cElementTree as ET
from cryptography.fernet import Fernet
from pathlib import Path
def load_key():
"""
Load the previously generated key
"""
return open("../login/secret.key", "rb").read()
def generate_key():
"""
Generates a key and save it into a file
"""
key = Fernet.generate_key()
with open("../login/secret.key", "wb") as key_file:
key_file.write(key)
def decrypt_message(encrypted_message):
"""
Decrypts an encrypted message
"""
key = load_key()
f = Fernet(key)
message = encrypted_message.encode('utf-8')
decrypted_message = f.decrypt(message)
return(decrypted_message)
def decryptMessage(StringToDecrypt):
decryptedMessage = decrypt_message(StringToDecrypt)
return decryptedMessage
def loginToRoster(chrome):
credentials = readXML()
user = decryptMessage(credentials[0])
pw = decryptMessage(credentials[1])
userName = chrome.find_element_by_id('UserName')
userName.send_keys(user)
password = chrome.find_element_by_id('Password')
password.send_keys(pw)
In the tuple "credentials" there are 2 encrypted strings.
Please help - have already tried everything to change the formats, but no chance.
Edit:
Errormessage:
Traceback (most recent call last):
File "C:/Users/r/Documents/GitHub/ServiceEvaluationRK/source/main.py", line 27, in <module>
login.loginToRoster(chrome)
File "C:\Users\r\Documents\GitHub\ServiceEvaluationRK\source\login.py", line 106, in loginToRoster
user = decryptMessage(credentials[0])
File "C:\Users\r\Documents\GitHub\ServiceEvaluationRK\source\login.py", line 49, in decryptMessage
decryptedMessage = decrypt_message(StringToDecrypt)
File "C:\Users\r\Documents\GitHub\ServiceEvaluationRK\source\login.py", line 43, in decrypt_message
decrypted_message = f.decrypt(message)
File "C:\Users\r\Documents\GitHub\ServiceEvaluationRK\venv\lib\site-packages\cryptography\fernet.py", line 75, in decrypt
timestamp, data = Fernet._get_unverified_token_data(token)
File "C:\Users\r\Documents\GitHub\ServiceEvaluationRK\venv\lib\site-packages\cryptography\fernet.py", line 107, in _get_unverified_token_data
raise InvalidToken
cryptography.fernet.InvalidToken
I found an answer to my problem:
I took ASCII instead of utf-8. And I added a .decode('ASCII') at the function "loginToRoster" to both variables 'user' and 'pw'
Now the encryption and decryption works fine.
So, the 'loginToRoster' functions looks like:
def loginToRoster(chrome):
credentials = readXML()
user = decryptMessage(credentials[0]).decode('ASCII')
pw = decryptMessage(credentials[1]).decode('ASCII')
userName = chrome.find_element_by_id('UserName')
userName.send_keys(user)
password = chrome.find_element_by_id('Password')
password.send_keys(pw)
Where have you defined load_key() in the decrypt_message function. It's not a method it's just a undefined function. You're probably getting that error since the key is invalid because you're not getting the one you saved.
I have a video file which I am trying decrypt . The key is stored in a file. For some reasons it's not working and giving me this error "TypeError: Object type <class 'str'> cannot be passed to C code"
DecryptFile function I wrote takes 3 parameters
input file name ("input.ts")
output file name ("output.ts")
key for decryption ("k.kjs").
What I want it to do is decrypt the file with the key provided and save it with output name I gave . I am using Python 3.7.1
from Crypto.Cipher import AES
import os
def DecryptFile(infile,outfile,keyfile):
data = open(infile,"rb").read()
key = open(keyfile,"rb").read()
print(type(data))
iv = '\x00'*15 + chr(1)
aes_crypter = AES.new(key, AES.MODE_CBC, iv)
a = aes_crypter.decrypt(data)
with open(outfile, 'wb') as out_file:
out_file.write(a)
DecryptFile("input.ts","output.ts","k.kjs")
According to [ReadTheDocs.PyCryptodome]: AES - Crypto.Cipher.AES.new(key, mode, *args, **kwargs), iv should be:
Of type bytes
A kwarg
To get past this error, modify 2 lines of your code:
# ...
iv = b'\x00' * 15 + b'\x01'
aes_crypter = AES.new(key, AES.MODE_CBC, iv=iv)
# ...
I'm trying to to encrypt a message using a given public key pubkey that i read off a file. When I try to run my program I get an error message stating that
'str' object has no attribute 'encrypt'.
I have already tried encoding the public key, but I am still getting the same error. Since I need to use these specific public key I cannot generate another random public key.
Following is my code:
from Crypto.PublicKey import RSA
import math
def text_to_int(text):
"""
Converts text into an integer for use in encryption.
input: text - a plaintext message
output: integer - an integer encoding text
"""
integer = 0
for char in text:
if integer > 0:
integer = integer*256
integer = integer + ord(char)
return integer
#Read public key
with open('C:\\Users\\alan9\\Downloads\\Assignement2\\Supporting_Files\\HLand_Key.pub', 'rb') as f:
read_key = f.read()
# use the PUBLIC KEY to encrypt a message:
message = "attack early next week"
message_int = text_to_int(message)
ciphertext = read_key.encrypt(message_int, None)
#Write ciphertext to file
with open('C:\\Users\\alan9\\Downloads\\Assignement2\\Supporting_Files\\cipher.txt', 'w') as f_write:
f_write.write(ciphertext)
I expect the output to return the encrypted message in a text file named cipher using the specified public key.
Any help will be appreciated!!!
I'm trying to set up encryption on a portion of a project that I'm working on. Right now, I'm trying an implementation similar to this. As an extra layer of security, I have all of my Python source code compiled into .pyd files via Cython. What I want to do is unencrypt a .pyd module, import it, and then delete the unencrypted file immediately afterwords while keeping the module available in memory. How do I do this?
Here is the code I'm using for encryption/decryption:
from hashlib import md5
from Crypto.Cipher import AES
from Crypto import Random
def derive_key_and_iv(password, salt, key_length, iv_length):
d = d_i = ''.encode()
while len(d) < key_length + iv_length:
d_i = md5(d_i + password.encode() + salt).digest()
d += d_i
return d[:key_length], d[key_length:key_length+iv_length]
def encrypt(in_file, out_file, password, key_length=32):
bs = AES.block_size
salt = Random.new().read(bs - len('Salted__'))
key, iv = derive_key_and_iv(password, salt, key_length, bs)
cipher = AES.new(key, AES.MODE_CBC, iv)
out_file.write('Salted__'.encode() + salt)
finished = False
while not finished:
chunk = in_file.read(1024 * bs)
if len(chunk) == 0 or len(chunk) % bs != 0:
padding_length = (bs - len(chunk) % bs) or bs
chunk += (padding_length * chr(padding_length)).encode()
finished = True
out_file.write(cipher.encrypt(chunk))
def decrypt(in_file, out_file, password, key_length=32):
bs = AES.block_size
salt = in_file.read(bs)[len('Salted__'):]
key, iv = derive_key_and_iv(password, salt, key_length, bs)
cipher = AES.new(key, AES.MODE_CBC, iv)
next_chunk = b''
finished = False
while not finished:
chunk, next_chunk = next_chunk, cipher.decrypt(in_file.read(1024 * bs))
if len(next_chunk) == 0:
padding_length = chunk[-1]
chunk = chunk[:-padding_length]
finished = True
out_file.write(chunk)
I am using a test module called test_me_pls with the following code, which is compiled into test_me_pls.pyd:
def square(x):
return x * x
To test, I have done the following:
>>> import os
>>> origpath = r'C:\test\test_me_pls.pyd'
>>> encpath = r'C:\test\blue.rrr'
>>> decpath = r'C:\test\test_me_pls.pyd'
>>> key = 'hello'
>>> with open(origpath,'rb') as inf, open(encpath,'wb') as outf:
... encrypt(inf,outf,key)
>>> os.remove(origpath)
>>> import test_me_pls
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'test_me_pls'
So far so good. I got the file encrypted and deleted the unencrypted .pyd file. Just to make sure it worked how I was expecting, I tried to import the deleted/encrypted module and the import failed as expected.
Next, I decrypt, import the module, and test it out:
>>> with open(encpath,'rb') as inf, open(decpath,'wb') as outf:
... decrypt(inf,outf,key)
>>> import test_me_pls
>>> test_me_pls.square(5)
25
Okay, decryption worked.
Now that I have the module imported, I want to delete the unencrypted .pyd file:
>>> os.remove('test_me_pls.pyd')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
PermissionError: [WinError 5] Access is denied: 'test_me_pls.pyd'
Okay. Not what I was hoping for. And just to beat a dead horse:
>>> test_me_pls.__file__
'.\\test_me_pls.pyd'
>>> os.remove(test_me_pls.__file__)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
PermissionError: [WinError 5] Access is denied: '.\\test_me_pls.pyd'
Is there a way to do this?
NOTE: I understand that if someone really wants to get at my code, it doesn't matter that I have it compiled and encrypted because if they know what they're doing they can still get to the unencrypted .pyd file by using a debugger and setting a break point at the appropriate spot, uncompiling the .pyd file, etc. etc. insert reverse engineering techniques here. What I do want is something that will prevent casual attempts to look at the code in this module. The lock on the front door to my house can easily be picked by someone with the right knowledge and tools, but that doesn't mean I don't want to bother locking my door.
2nd NOTE: If it makes any difference, I'm using Python 3.3
I found a workaround that ignores the specific PermissionError problem above but that solves the problem of decrypting a Python module and then running it from within Python without leaving a decrypted copy of the module on the disk for any amount of time.
Using this answer as a starting point, I decided to modify the decrypt function above to return a string rather than write to a file. Then I can import the string as a module and run the code from within Python--all while never saving the decrypted module to disk. Unfortunately, in order to accomplish this, I had to start with an encrypted .py file rather than an encrypted and compiled .pyd file like I originally wanted. (If anyone knows how to import a bytes object as a module, please let me know!)
Anyway, here are the specific changes I made to get it working.
First, the new decrypt function:
def decrypt(in_file, password, key_length=32):
bs = AES.block_size
salt = in_file.read(bs)[len('Salted__'):]
key, iv = derive_key_and_iv(password, salt, key_length, bs)
cipher = AES.new(key, AES.MODE_CBC, iv)
next_chunk = b''
b = b''
finished = False
while not finished:
chunk, next_chunk = next_chunk, cipher.decrypt(in_file.read(1024 * bs))
if len(next_chunk) == 0:
padding_length = chunk[-1]
chunk = chunk[:-padding_length]
finished = True
b += chunk
return b.decode() # Note: will only work if unencrypted file is text, not binary
Just to be thorough, let's encrypt the original file, delete the unencrypted file, and then decrypt, returning the source to a string, s:
>>> import os
>>> origpath = r'C:\test\test_me_pls.py'
>>> encpath = r'C:\test\blue.rrr'
>>> key = 'hello'
>>> with open(origpath,'rb') as inf, open(encpath,'wb') as outf:
... encrypt(inf,outf,key)
>>> os.remove(origpath)
>>> import test_me_pls
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named 'test_me_pls'
>>> with open(encpath,'rb') as inf:
... s = decrypt(inf,key)
Great! No unencrypted copy of the source is saved to disk. Now to import the string as a module:
>>> import sys, imp
>>> test_me_pls = imp.new_module('test_me_pls')
>>> exec(s, test_me_pls.__dict__)
>>> test_me_pls.square(7)
49
Then, for good measure, we can add the module to sys to get it to ignore subsequent attempts to import:
>>> sys.modules['test_me_pls'] = test_me_pls
And then because making it more difficult to read the source code was our original goal, let's get rid of the string that contains it:
>>> del s
And finally, just as a sanity check, make sure the module still works after the source string is gone:
>>> test_me_pls.square(3)
9
If anyone has any alternative solutions (especially how to fix that Windows PermissionError problem or import a binary .pyd from a bytes object rather than from a file), please let me know!