refactor aes.py, aes-buffer to use pycrypto

--HG--
branch : pmacs2
This commit is contained in:
Erik Osheim 2009-05-21 10:24:29 -04:00
parent 8be0f59be1
commit 254ba4b0bb
4 changed files with 56 additions and 123 deletions

133
aes.py Executable file → Normal file
View File

@ -1,112 +1,29 @@
#!/usr/bin/python
#
# by Erik Osheim
import os
from subprocess import Popen, PIPE
import Crypto.Hash.SHA256
import Crypto.Cipher.AES
class Cipher(object):
'''Cipher represents a particular hashing strategy (password, seed, and type). Cipher can encrypt or decrypt data.'''
def __init__(self, password, seed='aes.py', hashtype='rmd160'):
class Crypter(object):
ALIGNMENT = 16
def __init__(self, password, salt='aes.py'):
self.password = password
self.seed = seed
self.hashtype = hashtype
self.salt = salt
self.hash = Crypto.Hash.SHA256.new(password + salt)
self.cipher = Crypto.Cipher.AES.new(self.hash.digest())
def pad(self, s):
xtra = len(s) % self.ALIGNMENT
if xtra:
return s + '\x00' * (self.ALIGNMENT - xtra)
else:
return s
def unpad(self, s):
l = len(s)
while l > 0 and s[l - 1] == '\x00':
l -= 1
return s[:l]
def encrypt(self, data):
return encrypt_data(data, self.password, self.seed, self.hashtype)
def decrypt(self, encrypted):
return decrypt_data(encrypted, self.password, self.seed, self.hashtype)
return self.cipher.encrypt(self.pad(data))
def _check_aespipe():
'''This function checks if we have the "aespipe" binary in $PATH'''
result = os.system('which aespipe > /dev/null')
if result != 0:
raise Exception, "Could not find aespipe; is it installed?"
def encrypt_data(data, password, seed='aes.py', hashtype='rmd160'):
'''Uses password to encrypt data'''
_check_aespipe()
args = ["aespipe", "-S", seed, "-H", hashtype, "-p", "0"]
p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
(stdout, stdin, stderr) = (p.stdout, p.stdin, p.stderr)
stdin.write(password + '\n')
stdin.write(data)
stdin.close()
encrypted = stdout.read()
err = stderr.read()
if err:
raise Exception, "Problem: %s" % err
return encrypted
def encrypt_path(path, data, password, seed='aes.py', hashtype='rmd160'):
'''Uses password to encrypt data and writes result to path'''
encrypted = encrypt_data(data, password, seed, hashtype)
f = open(path, 'w')
f.write(encrypted)
f.close()
def decrypt_data(encrypted, password, seed='aes.py', hashtype='rmd160'):
'''Uses password to decrypt data'''
_check_aespipe()
args = ["aespipe", "-d", "-S", seed, "-H", hashtype, "-p", "0"]
p = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
(stdout, stdin, stderr) = (p.stdout, p.stdin, p.stderr)
stdin.write(password + '\n')
stdin.write(encrypted)
stdin.close()
data = stdout.read()
err = stderr.read()
if err:
raise Exception, "Problem: %s" % err
# data is null-padded at the end to align on 16 or 512 bytes boundaries
i = len(data)
while i > 1:
if data[i-1] == '\x00':
i -= 1
else:
break
return data[:i]
def decrypt_path(path, password, seed='aes.py', hashtype='rmd160'):
'''Uses password to decrypt data from path'''
f = open(path, 'r')
encrypted = f.read()
f.close()
data = decrypt_data(encrypted, password, seed, hashtype)
return data
if __name__ == "__main__":
import optparse, sys
parser = optparse.OptionParser()
parser.set_defaults(mode='decrypt')
parser.set_defaults(password='insecure1@3$5^')
parser.set_defaults(filename='output.aes')
parser.add_option('-e', dest='mode', action='store_const', const='encrypt',
help="perform encryption on data from stdin")
parser.add_option('-d', dest='mode', action='store_const', const='decrypt',
help="perform decryption on data from stdin")
parser.add_option('-f', dest='filename', action='store', metavar='FILENAME',
help="encrypt to/from FILENAME (default: output.aes)")
parser.add_option('-p', dest='password', action='store', metavar='PASSWORD',
default="insecure1@3$5^",
help="use password PASSWORD (default: insecure1@3$5^)")
(opts, args) = parser.parse_args()
c = Cipher(opts.password)
if opts.mode == 'encrypt':
data = sys.stdin.read()
encrypted = c.encrypt(data)
f = open(opts.filename, 'w')
f.write(encrypted)
f.close()
print "data written to %r." % opts.filename
else:
print "reading data from %r:" % opts.filename
f = open(opts.filename, 'r')
encrypted = f.read()
f.close()
data = c.decrypt(encrypted)
print data
def decrypt(self, data):
return self.unpad(self.cipher.decrypt(self.pad(data)))

View File

@ -5,7 +5,7 @@ import traceback
from subprocess import Popen, PIPE, STDOUT
import buffer, buffer.about, buffer.color, buffer.console, buffer.data
import buffer.fs
import buffer.fs, buffer.aes
import bufferlist, color, completer, ispell, keyinput, method, minibuffer
import mode, util, window
from point import Point
@ -369,7 +369,7 @@ class Application(object):
if not password:
raise Exception, "password is required"
if not os.path.exists(path) or os.path.isfile(path):
b = buffer.AesBuffer(path, password, name=name)
b = buffer.aes.AesBuffer(path, password, name=name)
else:
raise Exception, "not a file or dir: %r" % path
try:
@ -1014,7 +1014,7 @@ class Application(object):
def open_aes_file(path, name=None, binary=False):
if os.path.isfile(path) or not os.path.exists(path):
p = getpass.getpass("Please enter the AES password: ")
return buffer.AesBuffer(path, p, name)
return buffer.aes.AesBuffer(path, p, name)
else:
raise Exception, "can't open %r; unsupported file type" % path
def open_plain_file(path, name=None, binary=False):

View File

@ -1,7 +1,8 @@
from util import defaultdict
import codecs, datetime, grp, os, pwd, re, shutil, stat, string
import fcntl, select, pty, threading
import aes, dirutil, regex, highlight, lex, term
#import aes, dirutil, regex, highlight, lex, term
import dirutil, regex, highlight, lex, term
from point import Point
from subprocess import Popen, PIPE, STDOUT
from keyinput import MAP
@ -665,6 +666,7 @@ class FileBuffer(Buffer):
temp_path = self._temp_path()
shutil.copyfile(self.path, temp_path)
try:
data = self.make_string()
if self.windows[0].mode.savetabs:
@ -674,8 +676,9 @@ class FileBuffer(Buffer):
f2 = self._open_file_w(self.path, preserve=False)
f2.write(self.bytemark + data)
f2.close()
except:
except Exception, e:
if exists: shutil.copyfile(temp_path, self.path)
raise e
else:
self.store_checksum(data)
self.modified = False
@ -684,16 +687,16 @@ class FileBuffer(Buffer):
self.path = path
self.save()
class AesBuffer(FileBuffer):
btype = 'aesfile'
def __init__(self, path, password, name=None):
'''fb = FileBuffer(path)'''
FileBuffer.__init__(self, path, name)
self.password = password
def read_filter(self, data):
return aes.decrypt_data(data, self.password)
def write_filter(self, data):
return aes.encrypt_data(data, self.password)
#class AesBuffer(FileBuffer):
# btype = 'aesfile'
# def __init__(self, path, password, name=None):
# '''fb = FileBuffer(path)'''
# FileBuffer.__init__(self, path, name)
# self.password = password
# def read_filter(self, data):
# return aes.decrypt_data(data, self.password)
# def write_filter(self, data):
# return aes.encrypt_data(data, self.password)
class Binary32Buffer(FileBuffer):
btype = 'bin32file'

13
buffer/aes.py Normal file
View File

@ -0,0 +1,13 @@
import aes
from buffer import FileBuffer
class AesBuffer(FileBuffer):
btype = 'aesfile'
def __init__(self, path, password, name=None):
'''ab = AesBuffer(path, password)'''
FileBuffer.__init__(self, path, name)
self.crypter = aes2.Crypter(password)
def read_filter(self, data):
return self.crypter.decrypt(data)
def write_filter(self, data):
return self.crypter.encrypt(data)