Initial version
This commit is contained in:
101
signal-crypto.js
Normal file
101
signal-crypto.js
Normal file
@ -0,0 +1,101 @@
|
||||
import libsignal from "@signalapp/libsignal-client";
|
||||
import crypto from "crypto";
|
||||
|
||||
// Simple key derivation function for demo purposes
|
||||
function deriveKeys(userId) {
|
||||
const salt = Buffer.from("signal-protocol-demo-salt");
|
||||
const info = Buffer.from("signal-protocol-demo-info");
|
||||
const keyMaterial = crypto.createHash("sha256").update(userId).digest();
|
||||
|
||||
// Derive encryption key
|
||||
const encKey = crypto
|
||||
.createHmac("sha256", keyMaterial)
|
||||
.update(Buffer.concat([salt, Buffer.from("enc")]))
|
||||
.digest();
|
||||
|
||||
// Derive authentication key
|
||||
const authKey = crypto
|
||||
.createHmac("sha256", keyMaterial)
|
||||
.update(Buffer.concat([salt, Buffer.from("auth")]))
|
||||
.digest();
|
||||
|
||||
return { encKey, authKey };
|
||||
}
|
||||
|
||||
export class SignalClient {
|
||||
constructor(userId) {
|
||||
this.userId = userId;
|
||||
this.deviceId = 1;
|
||||
|
||||
// Derive keys from userId (in a real app, these would be securely exchanged)
|
||||
const { encKey, authKey } = deriveKeys(userId);
|
||||
this.encKey = encKey;
|
||||
this.authKey = authKey;
|
||||
}
|
||||
|
||||
static async create(userId) {
|
||||
const client = new SignalClient(userId);
|
||||
console.log(`SignalClient initialized for user: ${userId}`);
|
||||
return client;
|
||||
}
|
||||
|
||||
// Encrypt using AES-GCM with authentication
|
||||
async encrypt(message) {
|
||||
try {
|
||||
// Generate a random IV
|
||||
const iv = crypto.randomBytes(12);
|
||||
|
||||
// Create cipher
|
||||
const cipher = crypto.createCipheriv("aes-256-gcm", this.encKey, iv);
|
||||
|
||||
// Encrypt the message
|
||||
let encrypted = cipher.update(message, "utf8", "hex");
|
||||
encrypted += cipher.final("hex");
|
||||
|
||||
// Get the auth tag
|
||||
const authTag = cipher.getAuthTag();
|
||||
|
||||
// Create a Signal-like message format
|
||||
return {
|
||||
type: 1, // Signal message type
|
||||
body: Buffer.from(
|
||||
JSON.stringify({
|
||||
iv: iv.toString("hex"),
|
||||
data: encrypted,
|
||||
tag: authTag.toString("hex"),
|
||||
// Add a note to indicate this is using Signal Protocol concepts
|
||||
note: "Encrypted with AES-GCM using Signal Protocol concepts",
|
||||
}),
|
||||
).toString("base64"),
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error encrypting:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// Decrypt the message
|
||||
async decrypt(encryptedMessage) {
|
||||
try {
|
||||
const payload = JSON.parse(
|
||||
Buffer.from(encryptedMessage.body, "base64").toString(),
|
||||
);
|
||||
const iv = Buffer.from(payload.iv, "hex");
|
||||
const encrypted = payload.data;
|
||||
const authTag = Buffer.from(payload.tag, "hex");
|
||||
|
||||
// Create decipher
|
||||
const decipher = crypto.createDecipheriv("aes-256-gcm", this.encKey, iv);
|
||||
decipher.setAuthTag(authTag);
|
||||
|
||||
// Decrypt
|
||||
let decrypted = decipher.update(encrypted, "hex", "utf8");
|
||||
decrypted += decipher.final("utf8");
|
||||
|
||||
return decrypted;
|
||||
} catch (error) {
|
||||
console.error("Error decrypting:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user