SHOW:
|
|
- or go back to the newest paste.
1 | -- BoomCrypt - the simple file encryptor | |
2 | -- Not to be confused with bcrypt, the secure hashing function | |
3 | -- Written by MasterOfBooms/BoomBoomLHack | |
4 | - | -- version 1.2 |
4 | + | -- version 1.0 |
5 | -- Credits to SquidDev, ElvishJerricco, KillaVanilla, and Anavrins for their APIs | |
6 | ||
7 | - | local version = "1.2" |
7 | + | local version = "1.0" |
8 | - | local pbk = 1024 |
8 | + | os.loadAPI("sha") |
9 | - | os.loadAPI(".bc/sha") |
9 | + | os.loadAPI("b64") |
10 | - | os.loadAPI(".bc/b64") |
10 | + | os.loadAPI("aes") |
11 | - | os.loadAPI(".bc/aes") |
11 | + | os.loadAPI("rng") |
12 | - | os.loadAPI(".bc/rng") |
12 | + | os.loadAPI("json") |
13 | - | os.loadAPI(".bc/json") |
13 | + | |
14 | local args = {...} | |
15 | local tFile = args[2] | |
16 | local passBullet = string.char(7) | |
17 | local function PRNG() | |
18 | local r = 0 | |
19 | for i=1,math.random(128,512) do | |
20 | local g = math.random(32768) | |
21 | local s = math.random(4096) | |
22 | r=r+g | |
23 | r=r-s | |
24 | end | |
25 | return r | |
26 | end | |
27 | ||
28 | - | local function unloadAPI() |
28 | + | |
29 | - | os.unloadAPI("sha") |
29 | + | |
30 | - | os.unloadAPI("b64") |
30 | + | |
31 | - | os.unloadAPI("aes") |
31 | + | |
32 | - | os.unloadAPI("rng") |
32 | + | |
33 | - | os.unloadAPI("json") |
33 | + | |
34 | local iv = {} | |
35 | initCSPRNG() | |
36 | for i=1,16 do | |
37 | iv[i] = rng.random(1,255) | |
38 | end | |
39 | return iv | |
40 | end | |
41 | local function genKey(i) | |
42 | local s = sha.digest(i) | |
43 | local p = sha.pbkdf2(i,s,1024) | |
44 | return p:toHex() | |
45 | end | |
46 | local function byteToStr(bs) | |
47 | local str = "" | |
48 | - | local function genKey(i,iter) |
48 | + | |
49 | - | local hs = sha.digest(i) |
49 | + | |
50 | - | local ps = sha.hmac(i,hs) |
50 | + | |
51 | - | local p = sha.pbkdf2(i,ps,iter) |
51 | + | |
52 | return str | |
53 | end | |
54 | local function strToByte(str) | |
55 | local bs = {} | |
56 | for i=1,str:len() do | |
57 | local cha = string.byte(str:sub(i,i)) | |
58 | table.insert(bs,cha) | |
59 | end | |
60 | return bs | |
61 | end | |
62 | local function encrypt(pwd,msg) | |
63 | local key = genKey(pwd) | |
64 | local iv = genIV() | |
65 | local cr = aes.encrypt(key,msg,aes.AES256,aes.CTRMODE,iv) | |
66 | local bs = strToByte(cr) | |
67 | local out = b64.encode(bs) | |
68 | return out,iv | |
69 | end | |
70 | - | local function encrypt(pwd,msg,iter) |
70 | + | local function decrypt(pwd,msg,iv) |
71 | - | local key = genKey(pwd,iter) |
71 | + | local key = genKey(pwd) |
72 | local bs = b64.decode(msg) | |
73 | local ci = byteToStr(bs) | |
74 | local out = aes.decrypt(key,ci,aes.AES256,aes.CTRMODE,iv) | |
75 | return out | |
76 | end | |
77 | local function printUsage() | |
78 | - | local function decrypt(pwd,msg,iv,iter) |
78 | + | |
79 | - | local key = genKey(pwd,iter) |
79 | + | |
80 | print(progName.." <encrypt/decrypt> <file>") | |
81 | end | |
82 | local function fileOper(oper,file,data) | |
83 | if oper == "r" then | |
84 | local file = fs.open(file,"r") | |
85 | local out = file.readAll() | |
86 | file.close() | |
87 | return out | |
88 | - | print(progName.." <encrypt/decrypt> <file> [PBKDF2 iter]") |
88 | + | |
89 | elseif oper == "w" then | |
90 | local file = fs.open(file,"w") | |
91 | file.write(data) | |
92 | file.close() | |
93 | elseif oper == "d" then | |
94 | fs.delete(file) | |
95 | elseif oper == "e" then | |
96 | return fs.exists(file) | |
97 | end | |
98 | end | |
99 | ||
100 | print("BoomCrypt version "..version) | |
101 | if #args < 2 then | |
102 | printError("Not enough arguments!") | |
103 | printUsage() | |
104 | return | |
105 | end | |
106 | if args[1] == "encrypt" then | |
107 | if fileOper("e",tFile) then | |
108 | write("Password: ") | |
109 | local key = read(passBullet) | |
110 | write("Encrypting, please wait... ") | |
111 | local rf = fileOper("r",tFile) | |
112 | local fb = b64.encode(strToByte(rf)) | |
113 | - | if args[3] then |
113 | + | local cry,iv = encrypt(key,fb) |
114 | - | if tonumber(args[3]) < 1024 then |
114 | + | |
115 | - | local pbk = 1024 |
115 | + | |
116 | data["cryptData"] = cry | |
117 | - | pbk = tonumber(args[3]) |
117 | + | |
118 | data["cryptChecksum"] = sha.digest(cry):toHex() | |
119 | data["orginChecksum"] = sha.digest(fb):toHex() | |
120 | local out = json.encode(data) | |
121 | fileOper("d",tFile) | |
122 | fileOper("w",tFile,out) | |
123 | - | if #key < 8 then |
123 | + | |
124 | - | printError("Password must be 8 characters or more!") |
124 | + | |
125 | printError("File not found!") | |
126 | - | unloadAPI() |
126 | + | |
127 | end | |
128 | elseif args[1] == "decrypt" then | |
129 | if fileOper("e",tFile) then | |
130 | local data = json.decode(fileOper("r",tFile)) | |
131 | - | local cry,iv = encrypt(key,fb,pbk) |
131 | + | |
132 | printError("Invaild or corrupted BoomCrypt file!") | |
133 | return | |
134 | elseif not data["boomCrypt"] == version then | |
135 | printError("BoomCrypt file version mismatch") | |
136 | print("This BoomCrypt file is not compatible with this version of BoomCrypt.") | |
137 | return | |
138 | - | data["pbkdf2Iter"] = pbk |
138 | + | |
139 | if data["boomCrypt"] then | |
140 | write("Password: ") | |
141 | local key = read(passBullet) | |
142 | write("Decrypting, please wait... ") | |
143 | - | unloadAPI() |
143 | + | |
144 | local data = json.decode(rf) | |
145 | local fb = data["cryptData"] | |
146 | local iv = data["IV"] | |
147 | - | unloadAPI() |
147 | + | |
148 | local gs = data["orginChecksum"] | |
149 | local cryChk = sha.digest(fb):toHex() | |
150 | if not cryChk == cs then | |
151 | print("failed.") | |
152 | printError("Checksum mismatch: Encrypted data") | |
153 | return | |
154 | end | |
155 | local dey = decrypt(key,fb,iv) | |
156 | if not dey then | |
157 | print("failed.") | |
158 | printError("Invaild password!") | |
159 | - | unloadAPI() |
159 | + | |
160 | end | |
161 | local orgChk = sha.digest(dey):toHex() | |
162 | if not orgChk == gs then | |
163 | print("failed.") | |
164 | - | if #key < 8 then |
164 | + | |
165 | - | printError("Password must be 8 characters or more!") |
165 | + | |
166 | end | |
167 | - | unloadAPI() |
167 | + | |
168 | fileOper("d",tFile) | |
169 | fileOper("w",tFile,out) | |
170 | print("success!") | |
171 | else | |
172 | printError("Invaild or corrupted BoomCrypt file!") | |
173 | return | |
174 | end | |
175 | else | |
176 | - | local pbk = data["pbkdf2Iter"] |
176 | + | |
177 | end | |
178 | - | if not (cryChk == cs) then |
178 | + | |
179 | printError("Unrecognized subcommand!") | |
180 | printUsage() | |
181 | return | |
182 | - | unloadAPI() |
182 | + |