-
Notifications
You must be signed in to change notification settings - Fork 0
/
cipher.py
executable file
·105 lines (81 loc) · 2.95 KB
/
cipher.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python3
# -*- coding: latin-1 -*-
import hashlib
import optparse
import sys
from prng import Prng
import getpass
import utils
from StringIO import StringIO
import genkey
import hmac
version = "v0.3.1"
def cipher(message, key):
prng = Prng(deterministic=True, seed=key)
randomString = prng.getRandomBytes(len(message))
stream = StringIO()
for i in range(len(message)):
stream.write(chr(ord(message[i])^ord(randomString[i])))
return stream.getvalue()
MAGIC = "CWCI"
VERSION = 3
def authenticate(data, key):
sha = hashlib.sha256()
sha.update(data)
return hmac.new(key, sha.digest(), hashlib.sha256).digest()
def encrypt(plaintext, password):
nonce = Prng().getRandomBytes(32)
key = genkey.genKeyV3(password, nonce)
ciphertext = cipher(plaintext, key)
return MAGIC + utils.rawFromLong(VERSION, 16) + nonce + authenticate(ciphertext, key) + ciphertext
def decrypt(cipherfile, password):
if cipherfile[0:4] != MAGIC:
raise Exception("bad magic")
readVersion = utils.longFromRaw(cipherfile[4:6])
if readVersion != VERSION:
raise Exception("unknown version: %d" % readVersion)
nonce = cipherfile[6:38]
key = genkey.genKeyV3(password, nonce)
readMac = cipherfile[38:70]
ciphertext = cipherfile[70:]
mac = authenticate(ciphertext, key)
if readMac != mac:
raise Exception("bad authentication tag")
plaintext = cipher(ciphertext, key)
return plaintext
if __name__ == "__main__":
parser = optparse.OptionParser()
parser.add_option("-e", "--encrypt",
action="store", dest="filenameToEncrypt", default=None,
help="Input file to be encrypted")
parser.add_option("-d", "--decrypt",
action="store", dest="filenameToDecrypt", default=None,
help="Input file to be decrypted")
(options, args) = parser.parse_args()
if options.filenameToEncrypt and options.filenameToDecrypt:
print "cannot encrypt and decrypt at the same time"
sys.exit(1)
if not options.filenameToEncrypt and not options.filenameToDecrypt:
print "please provide a function to perform"
sys.exit(1)
password = getpass.getpass("password:")
if options.filenameToEncrypt:
f = open(options.filenameToEncrypt,"r")
plaintext = f.read()
f.close()
f = open(options.filenameToEncrypt+".encrypted","w")
f.write(encrypt(plaintext, password))
f.close()
print "File successfully encrypted"
elif options.filenameToDecrypt:
f = open(options.filenameToDecrypt,"r")
cipherfile = f.read()
f.close()
try:
plaintext = decrypt(cipherfile, password)
f = open(options.filenameToDecrypt + ".decrypted", "w")
f.write(plaintext)
f.close()
print "File successfully decrypted"
except Exception as e:
print e.message