簡體   English   中英

加密、編碼和 Python (AES)

[英]Encryption, encoding and Python (AES)

我正在嘗試在 python (python-Cypher, rhymes with decypher) 中編寫一個名為 P-Cypher 的加密/解密程序。 它使用 PyCrypto 庫對文件進行編碼(使用 AES)。 雖然我知道 Python,但我不知道密碼學 - 我這樣做是因為我認為它會很有趣,所以不要批評我的安全性。

這就是程序應該如何工作。

  1. 要求輸入文件。
  2. 詢問您是否希望它加密或解密。 (設置模式)
  3. 要求輸出文件。 驗證它存在 - 如果不存在,詢問您是否希望它創建一個。
  4. 加密輸入文件並告訴您密鑰/提示您輸入密鑰,並使用密鑰解密文件(取決於模式)
  5. 寫入輸出文件。

除了數字 4 之外,一切正常。(我知道第 5 步可以工作,因為第 5 步與上一個穩定版本 v0.03d 幾乎沒有變化)。 在第 4 步編碼中,會發生以下兩種情況之一,具體取決於我編碼的方式:

  1. 事情成功了 - 耶! 對文件進行編碼。 但是它打印出來的key是b'U\\xxx\\xxx\\xxx\\xxx\\xxx'這樣的形式。 當我在第 4 步解碼模式下輸入它時,無論有沒有 b 和 's,它都不起作用。 所以程序無法解密文件,使我的程序的一半無用。
  2. 我可以使用 .decode(encoding) 將其轉換為字符串。 這是您在下面的代碼中看到的方法。 然而,這是這種方式的問題——無論我使用什么編碼(ascii、ISO、windows-125x、EUR、Big5、utf-8、16 和 32 等),總是有一個或多個字節編碼不能編碼。 沒有編碼,就沒有解碼,使整個程序毫無用處。

所以我請你幫忙。 如果您能弄清楚如何解決問題 #1 或 #2(或者甚至兩者),我將不勝感激。

代碼——更新

# P-Cypher-Dev
# Made in 2015 by Mateo Guynn
# v0.04d
# Using AES 16/32/64-bit encryption (Google standard)
# DEV VERSION: Possibly unstable, contains better code.
# Changelog:
"""
v0.02d
- Improved Caesar Cipher
- Added binary Cipher converter (fail)
-------------FILE BROKEN------------
"""
"""
v0.03d
- Added ability to create new output files
- Fixed code not quitting on abort
- DEL : binary Cipher converter 
---------------STABLE---------------

"""
"""
v0.04d
- DEL : Caesar Cypher
- Added 16/32/64-byte AES encryption
- Binary and text now handled in same manner
-------------FILE BROKEN------------
(encryption works, decryption does not)

"""
"""
v0.05d
- Changed AES encryption to Google's way
- Fixed Key entry

"""
import os
import sys
from Crypto.Cipher import AES
from Crypto import Random
from Crypto.Util import randpool
import base64
import codecs

MAX_KEY_SIZE = 26 # Shows the number of available characters (26 in the alphabet)

 #NOTES: Binary mode only works if the file is named binary.dat.

def getMode():

    while True:

        eOrD = input('\nDo you wish to encrypt or decrypt a message? ')

        mode = eOrD.lower()

        if mode in 'encrypt e decrypt d'.split():

            return mode

        else:

            sys.exit('\nEnter either "encrypt" or "e" or "decrypt" or "d". Capital letters are allowed.\n')



def getMessage():


    inputFile = open(input('\nPlease enter the name of the file you want to encrypt/decrypt. You may use relative or full paths. \nPlease, remember the file extension(s)! ')).read()
    try:
        print ('\nThe contents of the file are: \n%s\n' % inputFile)
        return inputFile
    except IOError as e:
        sys.exit('Unable to open file (the file does not exist or P-Cypher does not have permission to view it).\n Aborting.')
    except FileNotFoundError as e:
        sys.exit('Unable to open file (the file does not exist or P-Cypher does not have permission to view it).\n Aborting.')


def getCipher(mode, message):
    block_size = 16 # For AES, this is the only working value
    key_size = 32 # Size of crypto key (possibly changes in getKey())
    aesmode = AES.MODE_CBC # More secure mode
    if mode[0] == 'e':
        key_bytes = randpool.RandomPool(512).get_bytes(key_size)
        open('decryption.key', 'wb+').write(key_bytes)
        print('\nYour keyfile is: decryption.key\n')
        pad = block_size - len(message) % block_size
        data = message + pad * chr(pad)
        iv_bytes = randpool.RandomPool(512).get_bytes(block_size)
        encrypted_bytes = iv_bytes + AES.new(key_bytes,aesmode,iv_bytes).encrypt(data)
        encrypted = base64.urlsafe_b64encode(encrypted_bytes)
        return encrypted
    else: 
        decryptb = base64.urlsafe_b64decode(message)
        decrypted_ivbytes = decryptb[:block_size]
        decrypt = decryptb[block_size:]
        print('\nAuto-searching for decryption.key...')
        try:
            key_bytes = base64.urlsafe_b64decode(open('decryption.key', 'rb').read())
        except IOError as io:
            key_bytes = base64.urlsafe_b64decode(open(input('decryption.key not found. If you have an alternate keyfile, please enter its name now. ')), 'rb').read
        except FileNotFoundError as fnf:
            key_bytes = base64.urlsafe_b64decode(open(input('decryption.key not found. If you have an alternate keyfile, please enter its name now. '), 'rb').read())
        decrypted = AES.new(key_bytes, aesmode, decrypted_ivbytes).decrypt(decryptb)
        pad = ord(decrypted[-1])
        decrypted = decrypted[:-pad]
        return decrypted
def getOutput():


    outputFile = input('\nPlease specify an output file. \nDon\'t forget the file extension! ')

    outputCheck = input('\nYour message will be encrypted/decrypted into the following output file: %s\n\nIs this okay? (y/n) ' % outputFile).lower()


    if outputCheck in 'y yes yeah ok'.split():

        try:
            return outputFile
        except IOError as ioerror:
            createNewFile = input('The file you specified does not exist. Shall I create one? (y/n) ')
            if createNewFile in 'y_yes_yeah_yes please_ok'.split('_'):
                oF = open(outputFile, 'w+')
                oF.close()
                return outputFile

            else:
                sys.exit('Aborting...')
    elif outputCheck in 'n no'.split():
        sys.exit('\nAborting...\n')
    else:
        sys.exit('\nAborting.\n')


print("\nP-Cypher Alpha starting up...\n\nv0.05 dev\nMateo Guynn\n2015\n")
mode = getMode()
message = getMessage()

try:
    open(getOutput(), 'wb+').write(getCipher(mode,message))
except IOError:
    sys.exit('Oh noes! Something has gone terribly wrong!')
except FileNotFoundError:
    sys.exit('Your input file was not found.')
print('\nDone.')

一種解決方案是將其編碼為十六進制...保證是ascii字符

import codecs
my_key = "U\x22\x54\x33"
print ("Your Key:", codecs.encode(my_key,"hex"))


...

my_decode_key = codecs.decode(input("enter key:"),"hex")
print( repr(my_decode_key))
print( my_decode_key == my_key )

我想我找到了自己的答案! 我真幼稚。 我假設字節輸出將是字母或數字。 實際上,我只是發現我的程序只是發出字節。 它們並不全是字母,數字甚至符號,這就是編碼不起作用的原因(至少是我的理解-如果我錯了,請糾正我)。

我更新了代碼以使用密鑰文件代替打印密鑰,現在加密就可以了! 但是,現在,在解密時,出現“ binascii.Error:不正確的填充”。 誰能幫助我解決這個問題? 我已經更新了問題中的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM