- Notifications
You must be signed in to change notification settings - Fork4
Threema Gateway Client for Java
License
marchof/three4j
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
A Java client library for theThreema Gatewaywhich supports exchanging end-to-end encrypted messages including images andarbitrary files. The primary purpose of this implementation is to provide asmall Maven artifact which can be easily integrated in any Java applications.The implementation is based on theJava 11 HTTP clientandSalty Coffee for NaCl encryption.
The following resources have been used to implement this API:
The API JavaDoc is availableonline.
The latest Three4J version can be obtained with the following Maven dependency:
<dependency> <groupId>com.mountainminds</groupId> <artifactId>three4j</artifactId> <version>1.5.0</version></dependency>
Latest builds frommaster are available in theMaven snapshot repository.
Three4J requires Java 11 or later.
To use this library you need aThreema Gatewayaccount with at least one Threema ID and the corresponding key pair. Three4Jcomes with a main class to generate a new key pair:
$ java com.mountainminds.three4j.KeyGeneratorPLEASE KEEP THE GENERATED KEYS CONFIDENTIAL IF YOU USE THEM WITH A THREEMA IDIF YOU LOOSE THE KEY OF A THREEMA ID IT CANNOT BE USED ANY MORE FOR MESSAGING public key: e25f5e489c458a9eb9d0c07ae44fba34a91b4bd20093e854400998abxxxxxxxxprivate key: 93f9873676db87ed2e3ec603645a360c529eb998b35afec17d7cd066xxxxxxxxPlease consultThreema's documentationhow to create a gateway Threema ID.
To use the gateway API client you need a gateway Threema ID and thecorresponding secret which was issued by the gateway admin interface:
ThreemaIdfrom =ThreemaId.of("*YOURGWY");// Insert your ID hereStringsecret =// e.g. "JSH5y9DfvOROm2Iw", retrieve this from a secure location
All requests are send through aGateway instance:
Gatewaygw =newGateway(from,secret);
If you want to send end-to-end encrypted messages (which is recommended)you need your private 32 byte Threema key. The hexadecimal stringrepresentation has 64 characters. Make sure you store this key securelyand do not make it available to others:
StringmyPrivateKeyStr =// retrieve this from a secure locationPrivateKeymyPrivateKey =KeyEncoder.decodePrivateKey(myPrivateKeyStr);
Sending a Threema message requires you to know the eight characterlong Threema ID of the receiver. Users may choose to register theirtelephone number or email address with their account which can thenbe queried to lookup their Threema ID. Note that we do not disclosethe actual data but only send hash values:
ThreemaIdreceiverId =gw.getIdByPhoneNumber(Hash.ofPhone("+41791234567"));System.out.println(receiverId);
Or by Email address:
receiverId =gw.getIdByEmailAddress(Hash.ofEmail("test@example.com"));System.out.println(receiverId);
Depending on the client the receiver might be able to process certainmessage types only. You can check the capabilities of a given ThreemaID:
System.out.println(gw.getCapabilities(receiverId));
To send a encrypted message we need the public key of the receiverwhich can be obtained via the gateway API. For better informationsecurity you should consider obtaining the public key physicallyfrom the receivers device e.g. from the QR code.
PublicKeyreceiverPublicKey =gw.getPublicKey(receiverId);
To ensure end-to-end encryption you create and encrypt the messagelocally before you send it to the gateway:
Stringtext =String.format("Secret message at %s.",Instant.now());PlainMessagemsg =newPlainMessage.Text(text);EncryptedMessageencrypted =msg.encrypt(myPrivateKey,receiverPublicKey);MessageIdmessageId =gw.sendMessage(receiverId,encrypted);System.out.println(messageId);
Sending images requires two steps. First we uploading the image as aencrypted blob. Similarly as for the actual message the encryptionkey for the blob is calculated from our private key and the receiverspublic key.
byte[]image =Files.readAllBytes(Path.of("src/test/resources/image.jpg"));Blobblob =Blob.newImage(myPrivateKey,receiverPublicKey);UploadedBlobuploadedBlob =gw.enrcryptAndUploadBlob(blob,image);
A reference to the uploaded blob needs then to be used in the image message:
PlainMessageimgMsg =newPlainMessage.Image(uploadedBlob);EncryptedMessageencrypted =imgMsg.encrypt(myPrivateKey,receiverPublicKey);gw.sendMessage(receiverId,encrypted);
We can also download and decrypt our image blob again:
byte[]downloadedImage =gw.downloadAndDecryptBlob(uploadedBlob);Files.write(Path.of("target/download.jpg"),downloadedImage);
We can encrypt and send arbitrary files. Files are encrypted with arandom key which is then transmitted with the corresponding message.An optional preview image can be added which must be encrypted withthe same key than the file:
byte[]file =Files.readAllBytes(Path.of("src/test/resources/document.pdf"));UploadedBlobuploadedFileBlob =gw.enrcryptAndUploadBlob(Blob.newFile(),file);byte[]thumbnail =Files.readAllBytes(Path.of("src/test/resources/thumbnail.png"));BlobthumbnailBlob =uploadedFileBlob.thumbnail();UploadedBlobuploadedThumbnailBlob =gw.enrcryptAndUploadBlob(thumbnailBlob,thumbnail);
Construction a file message requires a bit of meta data like the MIMEtype of the file.
PlainMessage.FilefileMsg =newPlainMessage.File(uploadedFileBlob,"application/pdf",RenderingType.DEFAULT);fileMsg.setThumbnail(uploadedThumbnailBlob);fileMsg.setFileName("document.pdf");EncryptedMessageencrypted =fileMsg.encrypt(myPrivateKey,receiverPublicKey);gw.sendMessage(receiverId,encrypted);
With abasic mode gateway ID you can directly send a plain textmessage to a given Threema ID without local encryption. The key pairis managed for you on the gateway server. Please rather considerusing end-to-end encryption as described above.
gw.sendSimpleMessage(ThreemaId.of("ABCDEFGH"),"Not so secret message.");
Alternatively you can also use a international telephone number or aemail address to send a message to if the users has registered themwith Threema. Note that the telephone number or the email address isdisclosed to the Threema gateway.
gw.sendSimpleMessageToPhoneNumber("41791234567","Not so secret message.");gw.sendSimpleMessageToEmailAddress("test@example.com","Not so secret message.");
Threema charges you for messages and blob uploads via the gateway.You can query the remaining credits via API:
System.out.println("Remaining credits: " +gw.getRemainingCredits());
To establich trust with your users you can create a QR code with yourThreema ID and your public key. When the user scans that QR code yourgateway ID will show "green" in their contact list. Theqrcode()method creates the text content which need to be converted to a QRgraphic with a library of your choice (e.g.zxing).
PublicKeypublicKey =KeyEncoder.getPublicKey(privateKey);Stringqrtext =KeyEncoder.qrcode(threemaid,publicKey);System.out.println(qrtext);
You can configure your own HTTP server to receive messages from theThreema gateway. The corresponding endpoint must be visible from thepublic internet of course. The payload can be decoded with theGatewayCallback class:
byte[]body =// unprocessed body received from the HTTP server of your choiceGatewayCallbackcallback =newGatewayCallback(body,secret);PublicKeypublicKey =gw.getPublicKey(callback.getFrom());PlainMessagemessage =callback.getMessage().decrypt(publicKey,myPrivateKey);System.out.println(message);
This project has been implemented for personal use only. There was noindependent security audit. Please perform your own security audit before usingthis software to send sensitive content!
Also make sure you never disclose a private key of a Threema ID. The privatekey will allow to send messages in your name and decode all content that hasbeen sent to you.
This code is provided "as is" under theMIT License, without warranty of any kind.
TheThreema Messenger and theMessaging Gatewayare products of Threema GmbH, Switzerland. This project has no affiliation toThreema GmbH. Please have a look at theirwebsite andconsider using their products for secure end-to-end encrypted communication.
About
Threema Gateway Client for Java
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Uh oh!
There was an error while loading.Please reload this page.