SrpcWorld
Elixir demo for SRPC security framework
Install / Use
/learn @knoxen/SrpcWorldREADME
SrpcWorld
A Secure Remote Password Cryptor Demo for Elixir
The Secure Remote Password Cryptor (SRPC) is a security framework based on the Secure Remote Password (SRP) protocol. SRPC builds on SRP to provide application-layer security for client/server communications. This provides a single entity trust model (no trusted third party) with mutual authentication and a host of other features. SRPC is transport independent. This demo uses HTTP.
The primary purpose of this demo is to show the touch points for Elixir application integration of the SRPC framework. Secondarily, the demo can be configured to use a client-side proxy to examine the structure of the SRPC messaging packets.
The SrpcWorld demo consists of the following server and client applications:
-
SrpcWorld.Serverprovides implementation for the following routes- Simple HTTP requests
/hello– says hello to thenamespecified in a URL request query string/reverse– reverses data provided in a URL request
- HTTP JSON API
/status– on/off status of a set of lights/action– control the on/off state of the lights
- Simple HTTP requests
-
SrpcWorld.Clientprovides a simple API to accessSrpcWorld.Serversimple HTTP requests -
SrpcWorld.Lightsprovides a simple API to accessSrpcWorld.ServerHTTP JSON API
SRPC framework functionality is added through SrpcPlug on the server side and SrpcClient on the client side.
<a name="TOC"></a>Table of Contents
- Install Elixir
- Compile SrpcWorld
- Start SrpcWorld
- Run SrpcWorld
- Inspect Traffic
- Client/Server Configuration
- Under the Hood
- Fin
<a name="Install"></a>Install Elixir
The Elixir language organization has detailed information regarding the installation of Elixir.
<div style="text-align: right">[Table of Contents](#TOC)</div><a name="Compile"></a>Compile SrpcWorld
In each of the client and server directories,
mix deps.get
mix compile
<div style="text-align: right">[Table of Contents](#TOC)</div>
<a name="Start"></a>Start SrpcWorld
In the server directory:
In the client directory:
Each directory contains an .iex.exs file that sets the IEx prompt to either client or server, followed by a ∴ sign.
<a name="Run"></a>Run SrpcWorld
HTTP calls
SrpcWorld.Client provides an API to access SrpcWorld.Server. For example, SrpcWorld.Client.say_hello/1 sends an HTTP GET /hello request to the server. However, we want this communication to be secure, so SrpcWorld.Client actually uses the SRPC framework to make the call. First, let's say hello to "Elixir" in the client IEx shell.
The SrpcWorld.Server is apparently vacationing in Hawai‘i as we see the say_hello response is Aloha Elixir.
The info log message received before the say_hello response informs us that the client connected to the SrpcWorld.Server at the specified URL. Whenever the SrpcWorld.Client makes a call, it reuses an SRPC connection maintained in its GenServer state. Since there was no existing connection, one was created in SrpcWorld.Client with the call:
{:ok, conn} = SrpcClient.connect()
SrpcClient.connect/0 returns a SrpcClient.Connection that is used to send secure messages to the SrpcWorld.Server. The connection is passed as the first parameter to SrpcClient functions such as in the implementation of SrpcWorld.Client.say_hello/1:
conn
|> SrpcClient.get("/hello?name=#{name}")
Subsequent SrpcWorld.Client calls reuse the same SrpcClient.Connection:
Controlling lights
SrpcWorld.Server fronts a set of virtual lights that can be controlled using the client-side SrpcWorld.Lights module. Controlling the lights requires a valid user login. The demo server includes setup of user srpc with password secret. To login, we use SrpcWorld.Lights.login/2:
If you've configured a proxy to observe SRPC traffic you'll see that no information regarding the user ID or password is visible (or leaks) during either SRPC registration or login messaging. In fact, the user password never leaves the client. The Under the Hood section describes what data is actually used to authenticate a user.
Let's get the status of the lights:
<pre><code class="elixir"><strong>client ∴</strong> SrpcWorld.Lights.status() %{"green" => "off", "red" => "off", "yellow" => "off"} </code></pre>All the lights are off. Let's turn the red light on:
<pre><code class="elixir"><strong>client ∴</strong> SrpcWorld.Lights.on("red") %{"green" => "off", "red" => "on", "yellow" => "off"} </code></pre>Now let's turn the green light on:
<pre><code class="elixir"><strong>client ∴</strong> SrpcWorld.Lights.on("green") %{"green" => "on", "red" => "on", "yellow" => "off"} </code></pre>Note the red light stayed on. We could use SrpcWorld.Lights.off/1 to turn the red light off, or we could use SrpcWorld.Lights.switch/1 which switches to a particular light and turns all others off:
In each of the above calls, SrpcWorld.Lights is sending HTTP JSON API requests to SrpcWorld.Server using SrpcClient.post/2. All the calls are secured via the SRPC framework.
<a name="Inspect"></a>Inspect Traffic
The demo can be configured to use a proxy to inspect the traffic between the SrpcWorld.Client and SrpcWorld.Server. Using such a proxy will reveal that all SRPC calls "look" identical. Each call is an HTTP POST to the URL http://host:port/ (where the host and port are specified in the configuration files). Neither the request nor response headers contain any meaningful demo application information. And the request and response bodies are encrypted. The bodies of an example request (top) and response (bottom) looks like:

<a name="Configure"></a>Configure SrpcWorld
Most of the demo configuration should not be changed. However, values of interest that can be changed on the server are host and port and on the client are port and an optional proxy setting.
SrpcWorld.Server
Server-side settings are in server/config/config.exs.
<a name="ServerConfig"></a>
:srpc_plug
Server-side SRPC framework functionality is provided by the SrpcPlug module. SrpcPlug shares a pre-defined relationship with the SrpcClient module used by SrpcWorld.Client. The server portion of this pre-defined relationship is contained in the server/priv/server.srpc file and should not be altered. The SRPC framework also requires a module that provides the SrpcHandler behaviour (to maintain server-side state for the SRPC framework).
config :srpc_plug,
srpc_file: "priv/server.srpc",
srpc_handler: SrpcWorld.Server.SrpcHandler
SrpcPlug is compiled with a time-limited demo of the SRPC framework that is valid for just over 3 hours after server startup. If the SrpcWorld.Server attempts to process a message through SrpcPlug after running for more than this time limit the plug will return a custom Fahrenheit 451 status code. Per the Plug documentation, this custom code status must be specified in the server configuration as follows:
config :plug, :statuses, %{
451 => "Srpc Demo Expired"
}
The SrpcWorld demo uses Cowboy for its HTTP server.
:cowboy
config :cowboy,
cowboy_opts: [
port: 8082,
acceptors: 5
]
The SrpcWorld.Server.SrpcHandler module uses
EntropyString to generate random connection IDs.
These settings configure the number of entropy bits in the ID, as well as the characters used.
:entropy_string
config :entropy_string,
bits: :session,
charset: :charset32
The SrpcWorld.Server.SrpcHandler module uses kncache (a simple cache) for maintaining server-side data. These settings configure the necessary caches and default TTLs.
:kncache
config :kncache,
caches: [
srpc_exch: 30,
srpc_nonce: 35,
srpc_conn: 3600,
srpc_reg: 3600,
user_data: 3600
]
SrpcWorld
Client-side settings are in client/config/config.exs.
Client-side SRPC framework functionality is provided by the SrpcClient module. SrpcClient shares a pre-defined relationship with the SrpcPlug module used by SrpcWorld.Server. The client portion of this pre-defined relationship is contained in the client/priv/client.srpc file and should not be altered.
SRPC is transport independent. This demo uses `S
Related Skills
node-connect
343.1kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
90.0kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
343.1kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
343.1kQQBot 富媒体收发能力。使用 <qqmedia> 标签,系统根据文件扩展名自动识别类型(图片/语音/视频/文件)。
