HTTPS/SSL calls with Lua and LuaSec

LuaSec module integrates with LuaSocket and provides HTTPS/SSL support for Lua socket operations. After you install LuaSocket and LuaSec, it only takes a couple of lines of code to make a call:

local https = require("ssl.https")
local body, code, headers, status = https.request("")

This should print HTTP/1.1 200 OK if your call is successful. If you need more control over the SSL configuration and the handshake steps, you can implement those steps yourself:

local ssl = require("ssl")

-- TLS/SSL client parameters (omitted)
local params = {
  mode = "client",
  protocol = "tlsv1",
  verify = "none",
  options = "all",

local conn = socket.tcp()
conn:connect("", 443)

-- TLS/SSL initialization
conn = ssl.wrap(conn, params)

conn:send("GET / HTTP/1.1\n\n")
local line, err = conn:receive()
print(err or line)

Again, the steps are simple: open a TCP connection on port 443 (this is a default port for HTTPS), wrap a socket connection into SSL with specified parameters, do a handshake, and then use regular send/receive methods. This code should print HTTP/1.1 200 OK if the request is successful or an error, if not.

This code doesn't use certificate verification as we explicitly specified verify="none" in the parameter list. Certificate verification allows the client (your script in this case) to confirm that the site it is connected to has access to a valid certificate, signed by a certificate authority. This is the same process that your web browser does for you when you connect to a website over https:. To enable certificate verification in SSL verify="none" needs to be replaced with verify="peer". This is not enough, however: if you run this code with verify="peer", you will get: certificate verify failed error.

This error indicates that we requested certificate verification, but have no means to verify this certificate as we don't have any certificate authority certificates we can use to validate the signature on the certificate provided by the website we are connecting to. To do that, we need to find and download the file with these certificates; it comes with your browser, but can also be found online. For example, this site has the file with certificates used by and included with Firefox. You can download the file, save it, and then specify the location of the saved file as one of the parameters for SSL:

local params = {
  mode = "client",
  protocol = "tlsv1",
  cafile = "/path/to/downloaded/cacert.pem", --<-- added cafile parameters
  verify = "peer", --<-- changed "none" to "peer"
  options = "all",

You can now use the same script to connect to (and other sites) over HTTPS and your script will verify the certificate provided by the site you are connected to.

You should get a copy of my slick ZeroBrane Studio IDE.


Great tutorial! Just what I was searching! Thanks :)

there is error: code: wrong version number

@icreator, you'll need to provide more information if you want me to investigate. I just tried both of the scripts and they work for me. I did find couple of references to "wrong version number" errors, which may be related to the difference between protocols used by the client or the server: 1 and 2. You may want to try changing "protocol" to "sslv3".

I was wondering if there was a way for using Lua to communicate with a binary interface like Apple Push Notification Service which expects data in binary format and fixed byte length and order.

@Parveen, this is most definitely possible. All you need is some library that would allow you to pack binary structures into strings as luasocket itself simply sends bytes. You may use something like vstruct ( to generate proper structures; more alternatives are listed on this page:

Hey, is it possible to import this on Corona SDK? Someone on the coronalabs forums suggested this method, I've tried importing the libraries to my project. However, I'm getting an error that I'm missing package.

Any help is appreciated, thanks!

Hi Yury, judging by the error message, Corona is trying to load ssl.code.lua file while it should be loading ssl/core.dll or ssl/ Make sure you have correct settings as describe here: You may also try network.request, which supports both http and https (

Hi I'm using marmalade quick and having same problem of Yuri, when I try to use ssl it returns me these errors. QUCKAPP ERROR: (./ssl.lua), line 9: module 'ssl.core' not found: no field package.preload['ssl.core'] no file './ssl/core.lua' no file '/usr/local/share/lua/5.1/ssl/core.lua' no file '/usr/local/share/lua/5.1/ssl/core/init.lua' no file '/usr/local/lib/lua/5.1/ssl/core.lua' no file '/usr/local/lib/lua/5.1/ssl/core/init.lua' no file './ssl/' no file '/usr/local/lib/lua/5.1/ssl/' no file '/usr/local/lib/lua/5.1/' I can't find any of these files in ssl library so I tried using luadist like what u said in another post ( hoping to find them, but it didn't work too. idk what else to do, help me please. Thanks

Mory, you are probably missing ssl.core binaries. You'll need to install openssl library (although you are likely to have it since you are on Linux) and find luasec binaries. It's possible that luadist installed those libraries you need, but Marmalade Quick is using its own folders for all the modules and libraries, so it doesn't see the modules installed by luadist. Paul.

If I put the code

require("socket") local https = require("ssl.https") local body, code, headers, status = https.request("") print(status)

I get nil as a result.

@christopher5106, what libraries do you use? I tested with the latest version of ZeroBrane Studio (v1.40, which now includes luasec libraries) and I get expected "HTTP/1.1 200 OK" result.

Leave a comment

what will you say?