Bayonne logo


This howto gives a short introduction to GNU ZRTP. The first part describes the overall structure of GNU ZRTP: the two main components (GNU ZRTP core and GNU ZRTP Java JMF/FMJ extension), and how they work together with applications. The second part shows some short programming examples.


  1. GNU ZRTP4J Overview
    1. The JMF/FMJ-specific extension ZrtpTransformConnector
    2. How GNU ZRTP4J, ccRTP, and applications work together
  2. Using GNU ZRTP4J
    1. How to instantiate a GNU ZRTP4J RTPConnector
    2. Start of the ZRTP discovery phase – Immediate and Auto Sensing
    3. Restart of the ZRTP discovery phase [TODO]

I. GNU ZRTP4J Overview

The complete GNU ZRTP4J implementation consists of two main components, the GNU ZRTP core and RTP/SRTP implementation specific glue code:

The JMF/FMJ-specific glue code provides the application interface to set up and control the behavior of GNU ZRTP4J. Applications never access the GNU ZRTP4J core directly.

1. The JMF/FMJ-specific extension ZrtpTransformConnector

ZrtpTransformConnector implements code that is specific to the RTP implementation of JMF/FMJ. ZrtpTransformConnector implements the RTPConnector interface code required by the JMF/FMJ RTPManager, and this class provides timeout handling to the GNU ZRTP4J core.

To perform its tasks, ZrtpTransformConnector

2. How GNU ZRTP4J, JMF/FMJ, and applications work together

GNU ZRTP4J provides a ZrtpUserCallback class that an application may extend and register with ZRTPTransformEngine. GNU ZRTP4J and ZRTPTransformEngine use the ZrtpUserCallback methods to report ZRTP events to the application. The application may display this information to the user or act otherwise.

The following figure depicts the relationships between ZRTPTransformEngine, JMF/FMJ RTPConnector, the GNU ZRTP4J core, and an application that provides a ZrtpUserCallback class.

         creates  |  ZrtpTransformConnector   |
       +----------+ extends TransformConnector|
       |          | implements RTPConnector   |
       |          +---------------------------+
       |                        |
       |                        | uses
       |                        |
  +----+-----------+      +-----+---------------+      +----------------+
  |  Application   |      |                     |      |                |
  |    creates     | uses | ZRTPTransformEngine | uses |   GNU ZRTP4J   |
  | ZRTP Connector +------+    implements       +------+      core      |
  |  and provides  |      |   ZrtpCallback      |      | implementation |
  |ZrtpUserCallback|      |                     |      |  (ZRtp et al ) |
  +----------------+      +---------------------+      |                |

The picture shows that ZRTPTransformEngine has a Janus face: one face to the application and one face to the GNU ZRTP4J core implementation. As an extension to the standard JMF/FMJ RTPConnector, ZRTPTransformEngine can provide the RTP/SRTP services to both the application and the GNU ZRTP4J core. The use relations are two-way use relations: the application uses the interface of ZrtpQueue to set up and control GNU ZRTP4J, and ZRTPTransformEngine uses the ZrtpUserCallback methods to report events to the application (if the application registered an own class that extends ZrtpUserCallback). On the other side, ZRTPTransformEngine instantiates the GNU ZRTP4J core class (ZRtp) and uses that interface to control ZRTP, mainly on behalf of the application. ZRTPTransformEngine also registers itself with the GNU ZRTP4J core providing the internal ZrtpCallback interface. GNU ZRTP4J uses this internal interface to access various services, for instance to send data via RTP session or timer support.


The following paragraphs show some short examples how to use GNU ZRTP4J. Most code snippets are extracted from the small demo programs located in the demo folder.

The GNU ZRTP4J source distribution contains a detailed documentation of the available methods.

1. How to instantiate a GNU ZRTP4J RTPConnector

The following short code snippets show how an application could instantiate a ZrtpTransformConnector, get the ZRTP4J engine and initialize it. Then the code gets a RTP manager instance and initializes it with the ZrtpTransformConnector. Plase note: in this case, the application must set the target address in the connector, not in the RTP manager.

    InetAddress ia = null;
    try {
        ia = InetAddress.getByName("localhost");
    } catch ( ex) {
        System.err.println("Unknown local host: " + ex.getMessage());

    SessionAddress sa = new SessionAddress(ia, 5002);
    SessionAddress target = new SessionAddress(ia, 5004);

    transConnector = (ZrtpTransformConnector)TransformManager
    zrtpEngine = transConnector.getEngine();
    zrtpEngine.setUserCallback(new MyCallback());
    if (!zrtpEngine.initialize("test_t.zid"))
        System.out.println("initialize failed");

    // initialize the RTPManager using the ZRTP connector

    mgr = RTPManager.newInstance();




This example uses different port numbers to set up the RTP receiver and transmitter. To use the ZRTP capabilities, the application has to initialize GNU ZRTP4J first. The statement


performs this initialization.

The string test_t.zid defines the name of a ZRTP Id file (ZID file) that stores the ZRTP identifier, the ZRTP retained secrets and some other data used by ZRTP. The initialize method may take a second parameter of type boolean to enable auto sensing mode (see below). If an application uses the simple form of the initialization method, then the auto sensing mode is assumed. An application can use setEnableZrtp(boolean onOff) to modify the auto sensing mode explicitely, for example if the application initialized ZRTP with auto sensing mode off.

Note: Currently, GNU ZRTP4J requires a ZID file, later versions may run without a ZID file. Running without a ZID file does not compromise security but may be less convenient for a user.

The initialization method opens the ZID file, performs some housekeeping, and enables ZRTP processing if no error occurred during the initialization phase. The application may now start the ZRTP discovery phase.


This method immediately starts the ZRTP discovery phase, and GNU ZRTP4J sends Hello packets to its peer. If the peer is already up and has ZRTP enabled, both will exchange Hello packets, negotiate the keys, compute the SRTP cryptographic data, and setup the SRTP session. Depending on the application's design and how the application uses GNU ZRTP4J, the ZRTP discovery and key exchange may overlap with RTP communication. Therefore the application may send some RTP data packet that are not protected by SRTP.

2. Start of the ZRTP discovery phase – Immediate and Auto Sensing

GNU ZRTP4J provides two ways to start the ZRTP discovery phase:

The next paragraphs describe these two modes in some more detail.

Immediate mode

If the application disabled auto sensing mode, then the application must start ZRTP by calling startZrtp(). GNU ZRTP4J immediately starts to send Hello packets to discover whether the peer is available and whether it supports ZRTP. If the peer supports ZRTP, then both parties continue with ZRTP handshake and negotiate the keys to set up SRTP.

If the peer is either not available or does not support ZRTP, then GNU ZRTP4J calls the user callback method zrtpNotSuppOther(). After this callback returns, GNU ZRTP4J does not disable ZRTP processing completely but switches into a detect state. See also Restart of the ZRTP discovery phase.

Auto Sensing mode

If ZRTP was initialized with auto sensing mode the application does not need to call startZrtp(). In auto sensing mode GNU ZRTP4J monitors the traffic on the RTP session to decide when to start the ZRTP discovery phase. GNU ZRTP4J starts the ZRTP discovery phase after at least one RTP packet was sent and received on the associated RTP session.

The auto sensing mode is convenient for applications that open RTP sessions, but the actual RTP traffic starts some time later. This is often the case for RTP applications that use a signaling protocol to exchange the actual RTP parameters (port numbers, IP address) with their peer applications. Even after the signaling was successful, the applications cannot exactly determine when data starts to flow on the RTP sessions. This starting time depends on a lot of factors, for example network delays or delays in the applications.

3. Restart of the ZRTP discovery phase