Using The Java Library
Getting the library
For Java projects:
<dependency>
<groupId>org.whispersystems</groupId>
<artifactId>libsignal-service-java</artifactId>
<version>(latest version here)</version>
</dependency>
For Android projects:
compile 'org.whispersystems:libsignal-service-android:(latest version here)'
Implementing the Signal Protocol interfaces
Signal Protocol is a stateful protocol, so libsignal-service users
need to implement the storage interface SignalProtocolStore
, which handles load/store
of your key and session information to durable media.
Creating keys
IdentityKeyPair identityKey = KeyHelper.generateIdentityKeyPair();
List<PreKeyRecord> oneTimePreKeys = KeyHelper.generatePreKeys(100);
PreKeyRecord lastResortKey = KeyHelper.generateLastResortKey();
SignedPreKeyRecord signedPreKeyRecord = KeyHelper.generateSignedPreKey(identityKey, signedPreKeyId);
The above keys are then stored locally so that they're available for load via the SignalProtocolStore
.
Registering
At install time, clients need to register with the Signal server.
private final String URL = "https://my.signal.server.com";
private final TrustStore TRUST_STORE = new MyTrustStoreImpl();
private final String USERNAME = "+14151231234";
private final String PASSWORD = generateRandomPassword();
SignalServiceAccountManager accountManager = new SignalServiceAccountManager(URL, TRUST_STORE,USERNAME, PASSWORD);
accountManager.requestSmsVerificationCode();
accountManager.verifyAccount(receivedSmsVerificationCode, generateRandomSignalingKey(), false, generateRandomInstallId());
accountManager.setGcmId(Optional.of(GoogleCloudMessaging.getInstance(this).register(REGISTRATION_ID)));
accountManager.setPreKeys(identityKey.getPublic(), lastResortKey, signedPreKey, oneTimePreKeys);
Sending text messages
SignalServiceMessageSender messageSender = new SignalServiceMessageSender(URL, TRUST_STORE, USERNAME, PASSWORD,
localRecipientId, new MySignalProtocolStore(),
Optional.absent());
messageSender.sendMessage(new SignalServiceAddress("+14159998888"),
SignalServiceDataMessage.newBuilder()
.withBody("Hello, world!")
.build());
Sending media messages
SignalServiceMessageSender messageSender = new SignalServiceMessageSender(URL, TRUST_STORE, USERNAME, PASSWORD,
localRecipientId, new MySignalProtocolStore(),
Optional.absent());
File myAttachment = new File("/path/to/my.attachment");
FileInputStream attachmentStream = new FileInputStream(myAttachment);
SignalServiceAttachment attachment = SignalServiceAttachment.newStreamBuilder()
.withStream(attachmentStream)
.withContentType("image/png")
.withLength(myAttachment.size())
.build();
messageSender.sendMessage(new SignalServiceAddress("+14159998888"),
SignalServiceDataMessage.newBuilder()
.withBody("An attachment!")
.withAttachment(attachment)
.build());
Receiving messages
SignalServiceMessageReceiver messageReceiver = new SignalServiceMessageReceiver(URL, TRUST_STORE, USERNAME, PASSWORD, mySignalingKey);
SignalServiceMessagePipe messagePipe;
try {
messagePipe = messageReciever.createMessagePipe();
while (listeningForMessages) {
SignalServiceEnvelope envelope = messagePipe.read(timeout, timeoutTimeUnit);
SignalServiceCipher cipher = new SignalServiceCipher(new MySignalProtocolStore());
SignalServiceDataMessage message = cipher.decrypt(envelope);
System.out.println("Received message: " + message.getBody().get());
}
} finally {
if (messagePipe != null)
messagePipe.close();
}
Updated less than a minute ago