Top Related Projects
A private messenger for Android.
A private messenger for iOS.
Matrix Client-Server SDK for JavaScript
A Matrix collaboration client for Android.
A glossy Matrix collaboration client for iOS
a free (libre) open source, mobile OS for Ethereum
Quick Overview
libsignal-protocol-java is a Java library that implements the Signal Protocol, a cryptographic protocol for secure end-to-end encrypted messaging. It provides the core cryptographic primitives and protocol logic used in the Signal messaging app and can be integrated into other applications requiring secure communication.
Pros
- Implements a well-established and audited encryption protocol
- Provides end-to-end encryption for messages, ensuring privacy and security
- Supports forward secrecy and deniability features
- Open-source, allowing for community review and contributions
Cons
- Requires careful implementation to ensure proper security
- May have a learning curve for developers unfamiliar with cryptographic concepts
- Limited to Java environments, which may not be suitable for all projects
- Requires ongoing maintenance to keep up with security updates and improvements
Code Examples
- Generating a key pair:
IdentityKeyPair identityKeyPair = KeyHelper.generateIdentityKeyPair();
- Creating a session builder:
SessionBuilder sessionBuilder = new SessionBuilder(sessionStore, preKeyStore, signedPreKeyStore,
identityKeyStore, recipientId, deviceId);
- Encrypting a message:
SessionCipher sessionCipher = new SessionCipher(sessionStore, recipientId, deviceId);
CiphertextMessage message = sessionCipher.encrypt("Hello, Signal!".getBytes());
- Decrypting a message:
SessionCipher sessionCipher = new SessionCipher(sessionStore, senderAddress);
byte[] plaintext = sessionCipher.decrypt(new SignalMessage(message.serialize()));
Getting Started
To use libsignal-protocol-java in your project:
- Add the dependency to your
build.gradle
file:
dependencies {
implementation 'org.whispersystems:signal-protocol-java:2.8.1'
}
- Initialize the necessary stores and generate keys:
IdentityKeyPair identityKeyPair = KeyHelper.generateIdentityKeyPair();
int registrationId = KeyHelper.generateRegistrationId(false);
PreKeyBundle preKeys = KeyHelper.generatePreKeys(startId, 100);
SignedPreKeyRecord signedPreKey = KeyHelper.generateSignedPreKey(identityKeyPair, 5);
// Store these values securely and implement the necessary store interfaces
- Create a session and start encrypting/decrypting messages using the examples provided above.
Competitor Comparisons
A private messenger for Android.
Pros of Signal-Android
- Full-featured Android app implementation of the Signal messaging protocol
- Includes user interface and complete messaging functionality
- Regularly updated with new features and security improvements
Cons of Signal-Android
- Larger codebase, potentially more complex to understand and contribute to
- Specific to Android platform, not portable to other environments
- May include non-core protocol features that increase maintenance overhead
Code Comparison
Signal-Android (UI-related code):
public class ConversationActivity extends PassphraseRequiredActivity
implements ConversationFragment.ConversationFragmentListener
{
private ConversationFragment fragment;
private InputPanel inputPanel;
}
libsignal-protocol-java (core protocol implementation):
public class SessionBuilder {
private final SessionStore sessionStore;
private final PreKeyStore preKeyStore;
private final SignedPreKeyStore signedPreKeyStore;
private final IdentityKeyStore identityKeyStore;
}
Summary
Signal-Android is a complete Android application implementing the Signal protocol, while libsignal-protocol-java is a lower-level library focusing on the core cryptographic protocol. Signal-Android offers a full user experience but is platform-specific, whereas libsignal-protocol-java provides a more portable, focused implementation of the protocol itself.
A private messenger for iOS.
Pros of Signal-iOS
- Full-featured iOS app implementation, providing a complete user experience
- Includes UI components and app-specific functionality
- Regularly updated with new features and improvements for iOS users
Cons of Signal-iOS
- Larger codebase, potentially more complex to understand and maintain
- iOS-specific, not suitable for cross-platform development
- May require more frequent updates to keep up with iOS changes
Code Comparison
Signal-iOS (Swift):
class SignalApp: UIApplication {
override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// iOS-specific app initialization
return true
}
}
libsignal-protocol-java (Java):
public class SignalProtocolAddress {
private final String name;
private final int deviceId;
public SignalProtocolAddress(String name, int deviceId) {
this.name = name;
this.deviceId = deviceId;
}
}
The Signal-iOS repository contains the complete iOS application, including UI and platform-specific features. In contrast, libsignal-protocol-java focuses on the core protocol implementation, making it more versatile for integration into various Java-based projects. While Signal-iOS provides a ready-to-use app for iOS users, libsignal-protocol-java offers greater flexibility for developers building custom applications with Signal protocol support across different platforms.
Matrix Client-Server SDK for JavaScript
Pros of matrix-js-sdk
- Broader functionality: Supports full Matrix protocol, including room management, user profiles, and more
- JavaScript-based: Easier integration with web applications and Node.js projects
- Active development: Regular updates and improvements
Cons of matrix-js-sdk
- Larger codebase: More complex and potentially harder to maintain
- Less focused: Not specialized for end-to-end encryption like libsignal-protocol-java
- Potentially slower: JavaScript execution may be less performant than Java
Code Comparison
matrix-js-sdk:
const client = sdk.createClient({
baseUrl: "https://matrix.org",
accessToken: "YOUR_ACCESS_TOKEN",
userId: "@alice:matrix.org"
});
libsignal-protocol-java:
SessionBuilder builder = new SessionBuilder(store, recipientId);
SessionCipher cipher = new SessionCipher(store, recipientId);
CiphertextMessage message = cipher.encrypt("Hello, world!".getBytes());
The matrix-js-sdk example shows client initialization, while libsignal-protocol-java demonstrates session building and message encryption. matrix-js-sdk focuses on high-level Matrix operations, whereas libsignal-protocol-java specializes in low-level cryptographic functions.
A Matrix collaboration client for Android.
Pros of Element Android
- Broader functionality: Full-featured Matrix client app, not just a protocol implementation
- Active development: More frequent updates and contributions
- Cross-platform support: Part of a larger ecosystem of Matrix clients
Cons of Element Android
- Larger codebase: More complex and potentially harder to maintain
- Specific to Matrix: Less flexible for use in other messaging applications
- Heavier resource usage: Full app consumes more device resources than a library
Code Comparison
Element Android (Kotlin):
class RoomListViewModel @Inject constructor(
private val session: Session,
private val roomListViewModelFactory: RoomListViewModelFactory
) : ViewModel() {
// Room list management logic
}
libsignal-protocol-java (Java):
public class SessionBuilder {
private final SessionStore sessionStore;
private final PreKeyStore preKeyStore;
private final SignedPreKeyStore signedPreKeyStore;
private final IdentityKeyStore identityKeyStore;
// Session building logic
}
The code snippets highlight the different focus areas: Element Android deals with UI and app-specific logic, while libsignal-protocol-java focuses on cryptographic protocol implementation.
A glossy Matrix collaboration client for iOS
Pros of Element iOS
- Full-featured Matrix client with a rich user interface
- Supports end-to-end encryption using the Matrix protocol
- Active development with frequent updates and new features
Cons of Element iOS
- Larger codebase and more complex than libsignal-protocol-java
- Specific to iOS platform, limiting cross-platform compatibility
- Focuses on client-side implementation rather than protocol library
Code Comparison
Element iOS (Swift):
class RoomEncryption: NSObject {
let algorithm: String
let rotationPeriodMs: UInt64
let rotationPeriodMsgs: UInt
init(algorithm: String, rotationPeriodMs: UInt64, rotationPeriodMsgs: UInt) {
self.algorithm = algorithm
self.rotationPeriodMs = rotationPeriodMs
self.rotationPeriodMsgs = rotationPeriodMsgs
}
}
libsignal-protocol-java (Java):
public class SessionBuilder {
private final SessionStore sessionStore;
private final PreKeyStore preKeyStore;
private final SignedPreKeyStore signedPreKeyStore;
private final IdentityKeyStore identityKeyStore;
private final Context context;
public SessionBuilder(SessionStore sessionStore,
PreKeyStore preKeyStore,
SignedPreKeyStore signedPreKeyStore,
IdentityKeyStore identityKeyStore,
Context context)
{
this.sessionStore = sessionStore;
this.preKeyStore = preKeyStore;
this.signedPreKeyStore = signedPreKeyStore;
this.identityKeyStore = identityKeyStore;
this.context = context;
}
}
a free (libre) open source, mobile OS for Ethereum
Pros of status-mobile
- Full-featured mobile application with a user interface, not just a protocol library
- Supports multiple cryptocurrencies and decentralized applications (dApps)
- Implements a broader range of features beyond secure messaging
Cons of status-mobile
- Larger codebase with more complexity due to its broader scope
- May have a steeper learning curve for developers new to blockchain technology
- Less focused on a single, specific protocol implementation
Code Comparison
status-mobile (React Native):
import React from 'react';
import { View, Text } from 'react-native';
import { connect } from 'react-redux';
const ChatScreen = ({ messages }) => (
<View>
{messages.map(message => <Text key={message.id}>{message.text}</Text>)}
</View>
);
libsignal-protocol-java (Java):
SessionBuilder builder = new SessionBuilder(store, recipientId);
SessionCipher cipher = new SessionCipher(store, recipientId);
CiphertextMessage message = cipher.encrypt("Hello, world!".getBytes());
byte[] plaintext = cipher.decrypt(new PreKeySignalMessage(message.serialize()));
The code snippets highlight the difference in focus between the two projects. status-mobile deals with UI components and state management, while libsignal-protocol-java focuses on cryptographic operations for secure messaging.
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual CopilotREADME
Overview
A ratcheting forward secrecy protocol that works in synchronous and asynchronous messaging environments.
PreKeys
This protocol uses a concept called 'PreKeys'. A PreKey is an ECPublicKey and an associated unique ID which are stored together by a server. PreKeys can also be signed.
At install time, clients generate a single signed PreKey, as well as a large list of unsigned PreKeys, and transmit all of them to the server.
Sessions
Signal Protocol is session-oriented. Clients establish a "session," which is then used for all subsequent encrypt/decrypt operations. There is no need to ever tear down a session once one has been established.
Sessions are established in one of three ways:
- PreKeyBundles. A client that wishes to send a message to a recipient can establish a session by retrieving a PreKeyBundle for that recipient from the server.
- PreKeySignalMessages. A client can receive a PreKeySignalMessage from a recipient and use it to establish a session.
- KeyExchangeMessages. Two clients can exchange KeyExchange messages to establish a session.
State
An established session encapsulates a lot of state between two clients. That state is maintained in durable records which need to be kept for the life of the session.
State is kept in the following places:
- Identity State. Clients will need to maintain the state of their own identity key pair, as well as identity keys received from other clients.
- PreKey State. Clients will need to maintain the state of their generated PreKeys.
- Signed PreKey States. Clients will need to maintain the state of their signed PreKeys.
- Session State. Clients will need to maintain the state of the sessions they have established.
Using libsignal-protocol
Configuration
On Android:
dependencies {
compile 'org.whispersystems:signal-protocol-android:(latest version number)'
}
For pure Java apps:
<dependency>
<groupId>org.whispersystems</groupId>
<artifactId>signal-protocol-java</artifactId>
<version>(latest version number)</version>
</dependency>
Install time
At install time, a libsignal client needs to generate its identity keys, registration id, and prekeys.
IdentityKeyPair identityKeyPair = KeyHelper.generateIdentityKeyPair();
int registrationId = KeyHelper.generateRegistrationId();
List<PreKeyRecord> preKeys = KeyHelper.generatePreKeys(startId, 100);
SignedPreKeyRecord signedPreKey = KeyHelper.generateSignedPreKey(identityKeyPair, 5);
// Store identityKeyPair somewhere durable and safe.
// Store registrationId somewhere durable and safe.
// Store preKeys in PreKeyStore.
// Store signed prekey in SignedPreKeyStore.
Building a session
A libsignal client needs to implement four interfaces: IdentityKeyStore, PreKeyStore, SignedPreKeyStore, and SessionStore. These will manage loading and storing of identity, prekeys, signed prekeys, and session state.
Once those are implemented, building a session is fairly straightforward:
SessionStore sessionStore = new MySessionStore();
PreKeyStore preKeyStore = new MyPreKeyStore();
SignedPreKeyStore signedPreKeyStore = new MySignedPreKeyStore();
IdentityKeyStore identityStore = new MyIdentityKeyStore();
// Instantiate a SessionBuilder for a remote recipientId + deviceId tuple.
SessionBuilder sessionBuilder = new SessionBuilder(sessionStore, preKeyStore, signedPreKeyStore,
identityStore, recipientId, deviceId);
// Build a session with a PreKey retrieved from the server.
sessionBuilder.process(retrievedPreKey);
SessionCipher sessionCipher = new SessionCipher(sessionStore, recipientId, deviceId);
CiphertextMessage message = sessionCipher.encrypt("Hello world!".getBytes("UTF-8"));
deliver(message.serialize());
Legal things
Cryptography Notice
This distribution includes cryptographic software. The country in which you currently reside may have restrictions on the import, possession, use, and/or re-export to another country, of encryption software. BEFORE using any encryption software, please check your country's laws, regulations and policies concerning the import, possession, or use, and re-export of encryption software, to see if this is permitted. See http://www.wassenaar.org/ for more information.
The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS), has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1, which includes information security software using or performing cryptographic functions with asymmetric algorithms. The form and manner of this distribution makes it eligible for export under the License Exception ENC Technology Software Unrestricted (TSU) exception (see the BIS Export Administration Regulations, Section 740.13) for both object code and source code.
License
Copyright 2013-2019 Open Whisper Systems
Licensed under the GPLv3: http://www.gnu.org/licenses/gpl-3.0.html
Top Related Projects
A private messenger for Android.
A private messenger for iOS.
Matrix Client-Server SDK for JavaScript
A Matrix collaboration client for Android.
A glossy Matrix collaboration client for iOS
a free (libre) open source, mobile OS for Ethereum
Convert
designs to code with AI
Introducing Visual Copilot: A new AI model to turn Figma designs to high quality code using your components.
Try Visual Copilot