How to prevent WiFi Password from being leaked from Lua code

#nodemcuesp8266lua

I have a Lua program which connects to a wifi network. The wifi password is hardcoded in the Lua code. I put the Lua code on an ESP8266 which runs on the NodeMCU firmware.

enter image description here

Here is the code I use:

wifi.setmode(wifi.STATION)
wifi.sta.config("SSID", "password")
wifi.sta.connect()

srv = net.createServer(net.TCP)
srv:listen(80,function(conn)
    conn:on("receive", function(conn, payload)
        print(payload)
        local response = "HTTP/1.1 200 OK\r\n\r\n<h1> Hello, NodeMcu.</h1>"
        conn:send(response, function()
            conn:close()
        end)
    end)
end)

When I use this setup for outdoor sensors anyone can grab the ESP8266, read the Lua script and get my WiFi password.

  1. Is there somewhere to encrypt the password on the ESP8266 with Lua?
  2. Is is possible to use some external crypto unit?
  3. Does compiled Lua code changes anything?

Best Answer

(Updated)

Within Lua code, there is no security on physical access. In addition to other answers: ESP have an option to save wifi settings. Thus this will allow you not putting credentials into a lua file. Program the credentials once and then remove credential code. This will make it a little bit harder to get the credentials. At least one who reads the code will not see it. (but of course not a total security option because of this.) Every time esp reboots or wifi network is in range, it will connect to the same ssid and network. This is on by default.

wifi.setmode(wifi.STATION)
wifi.sta.config("SSID", "password")
wifi.sta.connect()

Another way to do that is mac address registiration. If your AP allows you to register mac addresses of stations then it will provide one more layer of security since getting password will not be sufficient to connect the wifi network. This is not securing your password! You need to configure your AP to do that.

One more method: This will require more code. I cannot say it is more secure but it will make it harder to discover. You should compile your lua files to use this. Simply XOR your password with ssid and put the xor'ed version in your code. Survey the networks and create password for each network. Try to connect everyone with the produced pass. The matching pair will connect successfully. The others will fail. This will make connection sequence a little bit longer.

--encode
--retuns a table containing bytes
--also prints what should be in code
-- s is ssid, p is password
function encode(s,p)    
    key = s..s --encoding key, must be longer than password 
    enc = {} --new table
    uart.write(0,"Key output: {")

    for i=1,string.len(p) do        
        c = bit.bxor(p:byte(i),key:byte(i))
        table.insert(enc,c)     
        if i == string.len(p) then
            uart.write(0,c.."}")
        else 
            uart.write(0,c..",")
        end
    end 
    return enc
end

--decode
--tries to decode password with table enc
--s is ssid (got from survey) encval is byte table
function decode(s,encval)
    key=s..s
    pass=""
    for ii,i in ipairs(encval) do
        c = bit.bxor( key:byte(ii),i)
        pass = pass..string.char(c)
    end
    print("password: "..pass) 
    return pass
end

-- lets say ssid="network" and password="psswrd12"
encodedpass = encode("network","psswrd12")
-- this will print: Key output: {30,22,7,0,29,22,90,92}
-- this will be included in code
-- and to decode
print(decode("network",encodedpass))
-- will print: password: psswrd12
Related Topic