/api/rke/session
GETCreates a new RKE session by performing DKE (Distributed Key Exchange) with RAIDA servers to derive an encryption key for the specified Content Server.
Description
This endpoint creates an encrypted session with a Content Server using the DKE (Distributed Key Exchange) protocol. The process involves:
- DNS Discovery: Query the domain's DNS for RKE configuration
- Key Share Collection: Send
get_keysharerequests to 25 RAIDA servers - Key Derivation: XOR all received key shares together
- Key Expansion: Use HKDF-Expand to derive a 256-bit AES key
- Session Creation: Store the key in a session with unique ID
- The wallet must contain at least one authenticated coin for RAIDA encryption
- At least 13 RAIDA servers must respond with valid key shares
- The Content Server domain must have valid RKE DNS records
Derived keys are cached locally (default 24 hours TTL). If a valid cached key exists for the domain, it will be used instead of performing a new DKE operation, significantly improving performance.
Parameters
The Content Server domain to create a session with.
Format: Fully qualified domain name (FQDN)
Examples:
content.cloudcoin.globalmedia.example.com
Absolute path to the wallet containing coins for RAIDA authentication.
Format: Absolute filesystem path
Examples:
- Windows:
D:/CloudCoin/Wallets/DefaultorD:\CloudCoin\Wallets\Default - Linux/macOS:
/home/user/CloudCoin/Wallets/Default
Note: URL-encode the path if it contains special characters. Forward slashes work on all platforms.
Response
Returns the created session details including the session ID needed for encrypt/decrypt operations.
Response Properties (Success)
Example Response (Success)
{
"command": "rke_session_create",
"success": true,
"session_id": "a1b2c3d4e5f67890a1b2c3d4e5f67890",
"domain": "content.cloudcoin.global",
"cs_id": "CLOUDCOIN_CONTENT",
"expires_at": "2025-11-30T11:00:00Z",
"from_cache": false
}
Example Response (Error - DNS Discovery Failed)
{
"error": true,
"message": "DNS discovery failed",
"code": 500,
"result_code": 13
}
Complete Workflow Example
Here's a typical workflow for using RKE sessions:
const API_HOST = 'http://localhost:8080';
const DOMAIN = 'content.cloudcoin.global';
const WALLET = 'D:/CloudCoin/Wallets/Default';
// Step 1: Create a session
async function createSession() {
const url = `${API_HOST}/api/rke/session?domain=${DOMAIN}&wallet_path=${encodeURIComponent(WALLET)}`;
const response = await fetch(url);
const result = await response.json();
if (!result.success) {
throw new Error(result.message);
}
console.log(`Session created: ${result.session_id}`);
console.log(`Expires: ${result.expires_at}`);
console.log(`From cache: ${result.from_cache}`);
return result.session_id;
}
// Step 2: Encrypt data
async function encryptData(sessionId, plaintext) {
// Convert plaintext to base64
const base64 = btoa(plaintext);
const url = `${API_HOST}/api/rke/encrypt?session_id=${sessionId}&plaintext=${encodeURIComponent(base64)}`;
const response = await fetch(url);
const result = await response.json();
return {
ciphertext: result.ciphertext,
nonce: result.nonce
};
}
// Step 3: Decrypt data
async function decryptData(sessionId, ciphertext, nonce) {
const url = `${API_HOST}/api/rke/decrypt?session_id=${sessionId}&ciphertext=${encodeURIComponent(ciphertext)}&nonce=${nonce}`;
const response = await fetch(url);
const result = await response.json();
// Decode from base64
return atob(result.plaintext);
}
// Usage
async function main() {
const sessionId = await createSession();
// Encrypt a message
const encrypted = await encryptData(sessionId, 'Hello, Content Server!');
console.log('Encrypted:', encrypted);
// Decrypt it back
const decrypted = await decryptData(sessionId, encrypted.ciphertext, encrypted.nonce);
console.log('Decrypted:', decrypted);
}
main();
Examples
JavaScript (fetch)
const API_HOST = 'http://localhost:8080';
async function createRkeSession(domain, walletPath) {
const params = new URLSearchParams({
domain: domain,
wallet_path: walletPath
});
const response = await fetch(`${API_HOST}/api/rke/session?${params}`);
const result = await response.json();
if (result.success) {
// Store session ID for later use
sessionStorage.setItem('rke_session_id', result.session_id);
sessionStorage.setItem('rke_expires_at', result.expires_at);
console.log('Session created successfully');
console.log(`Session ID: ${result.session_id}`);
return result.session_id;
} else {
throw new Error(result.message);
}
}
// Create session for a Content Server
createRkeSession(
'content.cloudcoin.global',
'D:/CloudCoin/Wallets/Default'
);
cURL
# Create RKE session (Windows path)
curl "http://localhost:8080/api/rke/session?domain=content.cloudcoin.global&wallet_path=D%3A%2FCloudCoin%2FWallets%2FDefault"
# Create RKE session (Linux path)
curl "http://localhost:8080/api/rke/session?domain=content.cloudcoin.global&wallet_path=%2Fhome%2Fuser%2FCloudCoin%2FWallets%2FDefault"
# Extract session ID
curl "http://localhost:8080/api/rke/session?domain=content.cloudcoin.global&wallet_path=D%3A%2FCloudCoin%2FWallets%2FDefault" | jq -r '.session_id'
Go
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"net/url"
)
const ApiHost = "http://localhost:8080"
type SessionCreateResponse struct {
Command string `json:"command"`
Success bool `json:"success"`
SessionID string `json:"session_id"`
Domain string `json:"domain"`
CsID string `json:"cs_id"`
ExpiresAt string `json:"expires_at"`
FromCache bool `json:"from_cache"`
}
func CreateRkeSession(domain, walletPath string) (*SessionCreateResponse, error) {
apiUrl := fmt.Sprintf("%s/api/rke/session?domain=%s&wallet_path=%s",
ApiHost,
url.QueryEscape(domain),
url.QueryEscape(walletPath))
resp, err := http.Get(apiUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
var result SessionCreateResponse
json.Unmarshal(body, &result)
return &result, nil
}
func main() {
session, _ := CreateRkeSession(
"content.cloudcoin.global",
"D:/CloudCoin/Wallets/Default",
)
if session.Success {
fmt.Printf("Session ID: %s\n", session.SessionID)
fmt.Printf("Expires: %s\n", session.ExpiresAt)
}
}