0

I am trying to encrypt a file and then directly upload the encrypted file to SFTP using python.

At the moment, I am firstly storing the encrypted file into my local system and then pushing it into SFTP. Is it a way to directly push it to SFTP without storing it into my local system?

loyala
  • 175
  • 2
  • 13

1 Answers1

1

Encrypt

Encrypt and send file to remote server (encrypt_and_send.py):

from cryptography.fernet import Fernet
from io import BytesIO
import pysftp
from time import sleep

secret_key = b'fj6IO3olXODT7Z2xWjFoJkzg0qztYIkPtf-wDXwnwpY='

fernet = Fernet(secret_key)

with open('data.txt', 'rb') as file:
  original_data = file.read()

print('Data to encode:')
print(original_data.decode('utf-8'))

encrypted_data = fernet.encrypt(original_data)

print('Encrypted data:')
print(encrypted_data.decode('utf-8'))

file_like_object = BytesIO(encrypted_data)

with pysftp.Connection(host="192.168.1.18", username="root", password="password", log="/tmp/pysftp.log") as sftp:
  file_like_object.seek(0)
  sftp.putfo(file_like_object, 'output.txt')

print('sent')

Output:

Data to encode:
a
b
c
d
e
f

Encrypted data:
gAAAAABhE4sAq5iHkZ36H_vbVuBdlGrtLrQNpAXe-utbZT_JOHxnb1FipftlLiZcCO7AnkX_CEF4bz1oZk-CC57ubStE7u6k-w==
sent

Decrypt

Read data on remote machine (decrypt.py)

from cryptography.fernet import Fernet

secret_key = b'fj6IO3olXODT7Z2xWjFoJkzg0qztYIkPtf-wDXwnwpY='

fernet = Fernet(secret_key)
  
with open('output.txt', 'rb') as enc_file:
    encrypted = enc_file.read()
 
print(fernet.decrypt(encrypted).decode('utf-8'))

Output:

a
b
c
d
e
f

Additional info

when I run this script using pysftp==0.2.9 exception appear:

Exception ignored in: <function Connection.__del__ at 0x102941f70>
Traceback (most recent call last):
  File "/.../lib/python3.9/site-packages/pysftp/__init__.py", line 1013, in __del__
  File "/.../lib/python3.9/site-packages/pysftp/__init__.py", line 795, in close
ImportError: sys.meta_path is None, Python is likely shutting down

Looks like library problem.
pysftp==0.2.8 transfer data without any problems.

rzlvmp
  • 7,512
  • 5
  • 16
  • 45
  • Can the same method be used in case of uploading a csv file? This says that the file input should be byte type and not string. – loyala Aug 11 '21 at 09:37
  • Of course. csv is a usual txt file. You must read input file in binary mode: `with open('data.txt', 'rb') as file:` → `'rb'` means read binary in my example. If you reading file in usual mode `open(..., 'r')`, you need to use `from io import StringIO` and `file_like_object = StringIO(encrypted_data)`. – rzlvmp Aug 11 '21 at 09:43