Advertisement
LoganDark

LoganDark's Password System v4

May 17th, 2016
834
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.75 KB | None | 0 0
  1. -- http://www.computercraft.info/forums2/index.php?/topic/26148-logandarks-password-lock/
  2.  
  3. local pullEvent = os.pullEvent
  4. os.pullEvent = os.pullEventRaw
  5.  
  6. local pbkdf2 -- pbkdf2(data, salt, iter, dklen)
  7.  
  8. -- credit to Anavrins (http://www.computercraft.info/forums2/index.php?/user/12870-anavrins/) for the code in the following 'do' block
  9. do
  10.     local mod = 2^32
  11.     local sha_hashlen = 32
  12.     local sha_blocksize = 64
  13.     local band    = bit32 and bit32.band or bit.band
  14.     local bnot    = bit32 and bit32.bnot or bit.bnot
  15.     local bxor    = bit32 and bit32.bxor or bit.bxor
  16.     local blshift = bit32 and bit32.lshift or bit.blshift
  17.     local upack   = unpack
  18.     local function rrotate(n, b)
  19.         local s = n/(2^b)
  20.         local f = s%1
  21.         return (s-f) + f*mod
  22.     end
  23.     local function brshift(int, by) -- Thanks bit32 for bad rshift
  24.         local s = int / (2^by)
  25.         return s - s%1
  26.     end
  27.     local H = {
  28.         0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
  29.         0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
  30.     }
  31.     local K = {
  32.         0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
  33.         0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
  34.         0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
  35.         0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
  36.         0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
  37.         0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
  38.         0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
  39.         0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2,
  40.     }
  41.     local function incr(t, incr)
  42.         if 0xFFFFFFFF - t[1] < incr then
  43.             t[2] = t[2] + 1
  44.             t[1] = incr - (0xFFFFFFFF - t[1]) - 1      
  45.         else t[1] = t[1] + incr
  46.         end
  47.         return t
  48.     end
  49.     local function preprocess(data)
  50.         local len = #data
  51.    
  52.         data[#data+1] = 0x80
  53.         while #data%64~=56 do data[#data+1] = 0 end
  54.         local l = incr({0,0}, len*8)
  55.         for i = 2, 1, -1 do
  56.             data[#data+1] = band(brshift(band(l[i], 0xFF000000), 24), 0xFF)
  57.             data[#data+1] = band(brshift(band(l[i], 0xFF0000), 16), 0xFF)
  58.             data[#data+1] = band(brshift(band(l[i], 0xFF00), 8), 0xFF)
  59.             data[#data+1] = band(l[i], 0xFF)
  60.         end
  61.         return data
  62.     end
  63.     local function BE_toInt(bs, i)
  64.         return blshift((bs[i] or 0), 24) + blshift((bs[i+1] or 0), 16) + blshift((bs[i+2] or 0), 8) + (bs[i+3] or 0)
  65.     end
  66.     local function digestblock(data, i, C)
  67.         local w = {}
  68.         for j = 1, 16 do w[j] = BE_toInt(data, i+(j-1)*4) end
  69.         for j = 17, 64 do
  70.             local v = w[j-15]
  71.             local s0 = bxor(bxor(rrotate(w[j-15], 7), rrotate(w[j-15], 18)), brshift(w[j-15], 3))
  72.             local s1 = bxor(bxor(rrotate(w[j-2], 17), rrotate(w[j-2], 19)), brshift(w[j-2], 10))
  73.             w[j] = (w[j-16] + s0 + w[j-7] + s1)%mod
  74.         end
  75.         local a, b, c, d, e, f, g, h = upack(C)
  76.         for j = 1, 64 do
  77.             local S1 = bxor(bxor(rrotate(e, 6), rrotate(e, 11)), rrotate(e, 25))
  78.             local ch = bxor(band(e, f), band(bnot(e), g))
  79.             local temp1 = (h + S1 + ch + K[j] + w[j])%mod
  80.             local S0 = bxor(bxor(rrotate(a, 2), rrotate(a, 13)), rrotate(a, 22))
  81.             local maj = bxor(bxor(band(a, b), band(a, c)), band(b, c))
  82.             local temp2 = (S0 + maj)%mod
  83.             h, g, f, e, d, c, b, a = g, f, e, (d+temp1)%mod, c, b, a, (temp1+temp2)%mod
  84.         end
  85.         C[1] = (C[1] + a)%mod
  86.         C[2] = (C[2] + b)%mod
  87.         C[3] = (C[3] + c)%mod
  88.         C[4] = (C[4] + d)%mod
  89.         C[5] = (C[5] + e)%mod
  90.         C[6] = (C[6] + f)%mod
  91.         C[7] = (C[7] + g)%mod
  92.         C[8] = (C[8] + h)%mod
  93.         return C
  94.     end
  95.     local mt = {
  96.         __tostring = function(a) return string.char(unpack(a)) end,
  97.         __index = {
  98.             toHex = function(self, s) return ("%02x"):rep(#self):format(unpack(self)) end,
  99.             isEqual = function(self, t)
  100.                 if type(t) ~= "table" then return false end
  101.                 if #self ~= #t then return false end
  102.                 local ret = 0
  103.                 for i = 1, #self do
  104.                     ret = bit32.bor(ret, bxor(self[i], t[i]))
  105.                 end
  106.                 return ret == 0
  107.             end
  108.         }
  109.     }
  110.     local function toBytes(t, n)
  111.         local b = {}
  112.         for i = 1, n do
  113.             b[(i-1)*4+1] = band(brshift(band(t[i], 0xFF000000), 24), 0xFF)
  114.             b[(i-1)*4+2] = band(brshift(band(t[i], 0xFF0000), 16), 0xFF)
  115.             b[(i-1)*4+3] = band(brshift(band(t[i], 0xFF00), 8), 0xFF)
  116.             b[(i-1)*4+4] = band(t[i], 0xFF)
  117.         end
  118.         return setmetatable(b, mt)
  119.     end
  120.     local function digest(data)
  121.         data = data or ""
  122.         data = type(data) == "string" and {data:byte(1,-1)} or data
  123.         data = preprocess(data)
  124.         local C = {upack(H)}
  125.         for i = 1, #data, 64 do C = digestblock(data, i, C) end
  126.         return toBytes(C, 8)
  127.     end
  128.     local function hmac(input, key)
  129.         local input = type(input) == "table" and {upack(input)} or {tostring(input):byte(1,-1)}
  130.         local key = type(key) == "table" and {upack(key)} or {tostring(key):byte(1,-1)}
  131.         local blocksize = sha_blocksize
  132.         key = #key > blocksize and digest(key) or key
  133.         local ipad = {}
  134.         local opad = {}
  135.         local padded_key = {}
  136.         for i = 1, blocksize do
  137.             ipad[i] = bxor(0x36, key[i] or 0)
  138.             opad[i] = bxor(0x5C, key[i] or 0)
  139.         end
  140.         for i = 1, #input do
  141.             ipad[blocksize+i] = input[i]
  142.         end
  143.         ipad = digest(ipad)
  144.         for i = 1, blocksize do
  145.             padded_key[i] = opad[i]
  146.             padded_key[blocksize+i] = ipad[i]
  147.         end
  148.         return digest(padded_key)
  149.     end
  150.     function pbkdf2(data, salt, c, dklen)
  151.         local out = {}
  152.         local hashlen = sha_hashlen
  153.         local block = 1
  154.         dklen = dklen or 32
  155.    
  156.         while dklen > 0 do
  157.             local ikey = {}
  158.             local isalt = type(salt) == "table" and {upack(salt)} or {tostring(salt):byte(1,-1)}
  159.             local clen = dklen > hashlen and hashlen or dklen
  160.             isalt[#isalt+1] = band(brshift(band(block, 0xFF000000), 24), 0xFF)
  161.             isalt[#isalt+1] = band(brshift(band(block, 0xFF0000), 16), 0xFF)
  162.             isalt[#isalt+1] = band(brshift(band(block, 0xFF00), 8), 0xFF)
  163.             isalt[#isalt+1] = band(block, 0xFF)
  164.             for j = 1, c do
  165.                 isalt = hmac(isalt, data)
  166.                 for k = 1, clen do ikey[k] = bxor(isalt[k], ikey[k] or 0) end
  167.                 if j % 200 == 0 then os.queueEvent("PBKDF2", j) coroutine.yield("PBKDF2") end
  168.             end
  169.             dklen = dklen - clen
  170.             block = block+1
  171.             for k = 1, clen do out[#out+1] = ikey[k] end
  172.         end
  173.         return setmetatable(out, mt)
  174.     end
  175. end
  176.  
  177. local password
  178. local salt
  179. local version = 4
  180. local passVersion = version
  181.  
  182. function code(data, salt)
  183.     return pbkdf2(data, salt, 64, 32):toHex()
  184. end
  185.  
  186. function clear(ln)
  187.     if not ln then
  188.         term.clear()
  189.         term.setCursorPos(1, 1)
  190.     else
  191.         local x, y = term.getCursorPos()
  192.         set(ln)
  193.         term.setCursorPos(x, y)
  194.     end
  195. end
  196.  
  197. function set(y)
  198.     term.setCursorPos(1, y)
  199.     term.clearLine()
  200. end
  201.  
  202. function clr(clr)
  203.     if term.isColor() or clr == colors.gray or clr == colors.white then
  204.         term.setTextColor(clr)
  205.     end
  206. end
  207.  
  208. function genSalt()
  209.     local seed = "Vh1SoDi6F1w0ZtUcW5bY2jRm789BaMfArOsPdTpIzQp4CqKkGgPy3HvExXuJeNn"
  210.     local s = ""
  211.     for i = 1, 32 do
  212.         math.randomseed(math.random(0, 65534))
  213.         local l = math.random(1, seed:len())
  214.         s = s .. seed:sub(l, l)
  215.     end
  216.     return s
  217. end
  218.  
  219. function secure(msg)
  220.     if not salt then
  221.         salt = genSalt()
  222.     end
  223.     clear()
  224.     clr(colors.white)
  225.     print("Hashing...")
  226.     msg = code(msg, salt)
  227.     clear()
  228.     return msg, salts
  229. end
  230.  
  231. function keyWait(time)
  232.     print("Press any key to continue")
  233.     parallel.waitForAny(
  234.         function()
  235.             sleep(time)
  236.         end,
  237.         function()
  238.             os.pullEvent("key")
  239.         end
  240.     )
  241. end
  242.  
  243. if fs.exists("password.secure") then
  244.     local handle = fs.open("password.secure", "r")
  245.     passVersion = tonumber(string.match(handle.readLine(), "%d+"))
  246.     password = handle.readLine()
  247.     salt = handle.readLine()
  248.     handle.close()
  249. end
  250.  
  251. if (not password) or (passVersion < version) then
  252.     while true do
  253.         clear()
  254.         clr(colors.white)
  255.         if passVersion < version then
  256.             print("Enter password to upgrade")
  257.         else
  258.             print("Choose a password")
  259.         end
  260.         set(3)
  261.         clr(colors.gray)
  262.         print("V" .. version)
  263.         clr(colors.white)
  264.         set(2)
  265.         local input = read("*")
  266.         clear(2)
  267.         set(1)
  268.         print("Repeat your password")
  269.         set(2)
  270.         local input2 = read("*")
  271.         if input == input2 then
  272.             clear()
  273.             password = secure(input)
  274.             local handle = fs.open("password.secure", "w")
  275.             handle.writeLine(version)
  276.             handle.writeLine(password)
  277.             handle.writeLine(salt)
  278.             handle.close()
  279.             break
  280.         else
  281.             clear()
  282.             clr(colors.red)
  283.             print("Passwords do not match")
  284.             sleep(1)
  285.         end
  286.     end
  287. end
  288.  
  289. while true and (passVersion <= version) do
  290.     clear()
  291.     clr(colors.white)
  292.     print("Enter your password")
  293.     set(3)
  294.     clr(colors.gray)
  295.     print("V" .. version)
  296.     clr(colors.white)
  297.     set(2)
  298.     local input = read("*")
  299.     input = secure(input)
  300.     if input == password then
  301.         clr(colors.green)
  302.         print("Access granted")
  303.         set(3)
  304.         clr(colors.white)
  305.         keyWait(2);
  306.         set(3)
  307.         break
  308.     else
  309.         clear()
  310.         clr(colors.red)
  311.         print("Incorrect password")
  312.         sleep(1)
  313.     end
  314. end
  315.  
  316. os.pullEvent = pullEvent
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement