Skip to content

Cryptography

Thomas Schwotzer edited this page Sep 11, 2020 · 37 revisions

This library helps to encrypt / decrypt and sign and verify your data. It supports both, point-to-point-encryption and end-to-end-encryption. This is not a introduction to cryptography.

Point-to-point security

An ASAP session is initiated when ASAP peers encounter each other. ASAP protocol data units are transmitted during that session from one peer to another. We call it a point-to-point connection. PDUs are not encrypted or signed per default. Maybe it is not even necessary. It depends on the used protocol. If you find you protocol safe enough, you can avoid any additional security settings.

Switching signing and encryption on is simple:

ASAPPeer alicePeer = ... // was created somewhere 
alicePeer.getASAPCommunicationControl().setSendEncryptedMessages(true);
alicePeer.getASAPCommunicationControl().setSendSignedMessages(true);

There are four setting. You can choose to send signed and/or encrypted PDUs. You need access the ASAPCommunicationSetting set encryption and or signing on or off. Both are switched on in our example.

Any PDU issued by alicePeer would now be signed and encrypted. Signing works anytime if the security environment had been setup accordingly. The PDU would be signed with Alice’ private key. This signature is attached to the ASAP message.

Encryption can fail if alicePeer has no public key of the recipient. That is the peer with which Alice has running ASAP session. Nothing would happens in that case. Alice would not send any data.

Peers can define that they only accept signed or encrypted PDUs.

alicePeer.getASAPEnginePermissionSettings().setReceivedMessagesMustBeEncrypted(true);
alicePeer.getASAPEnginePermissionSettings().setReceivedMessagesMustBeSigned(true);

Encryption works anytime if the security environment had been setup accordingly and sender used the valid public key of Alice.

alicePeer would only process PDUs which encrypted and the signature can be verified. Verifying can fail for two reasons: alicePeer has a public key of the encountered peer but cannot verify the signature. In that case, the sender cheats about its identity or alicePeer has a wrong public key. Second reason is a missing public key on alicePeer side. Either way, the PDU is not processed.

End-to-end security

ASAP is a routing protocol. Messages can be send over an arbitrary number of peers (we call those exchanges hops) to its recipient. There are lot of good reasons to ensure end-to-end-security: Sender encrypts data for a dedicated recipient. Peer in between would transfer messages but without being able to read the content.

End-to-end-security is about your application data - the content in your ASAP message. Point-to-point-security is about signing the whole PDU. Quite often, it is also a good idea to sign a message. If you feel it useful keep reading.

BasicCryptoParameters

We defined an interface BasicCryptoParameters. Here is a part of the interface:

public interface BasicCryptoParameters {
    PrivateKey getPrivateKey() throws ASAPSecurityException; // get peers' private key
    PublicKey getPublicKey(CharSequence subjectID) throws ASAPSecurityException; // get public key of a peer
    PublicKey getPublicKey() throws ASAPSecurityException; // get peers' public key
}

You don't need to call those message yourself. You just need a refernce to an object implementing this interface, see Setup security environment.

More important, there is a class ASAPCryptoAlgorithms which offers very convient ways to do all that nice crypto stuff we need. That's what we discuss in the next sub sections.

Signing

You application is made up of peers who exchanges messages. Your message structure is opaque to ASAP. They are just an array of bytes. Signing is simple:

BasicCryptoParameters basicCryptoParameters; // see above
ASAPEngine yourEngine = ... // engine of your app
CharSequence yourUri = ... // optional uri describing your message in your app
byte yourMessage = ... // your application message
byte[] signature = ASAPCryptoAlgorithms.sign(message, basicCryptoParameters); // sign your message

// produce a message with attached signature
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// add signer name - make verification easier.
ASAPSerialization.writeCharSequenceParameter("Alice", baos);
// add actual message
ASAPSerialization.writeByteArray(message, baos); // message has three parts: content, sender, receiver
// finally: append signature
ASAPSerialization.writeByteArray(signature, baos);
// attach signature to message
byte yourSignedMessage = baos.toByteArray();

// let ASAP transmit your signed message.
yourEngine.add(yourURI, yourSignedMessage);

First view lines should look familiar. An ASAP engine was produced, a uri defined. You already created a message and plan to disseminate it with ASAP. But you are going to sign it first. It is just a single line of code. Call ASAPCryptoAlgorithms.sign.

A signature is produced. Signing requires your private key that is provided by our BasicCryptoParameters object, see later. This signature should be transmitted with your data. We produce now a message that consists of three parts: Signer name, signed message and signature. This library provides class ASAPSerialization which makes producing and parsing ASAP related structures to byte arrays very easy. This class is used to produce ASAP PDUs and can help us here as well.

This signed message can now be transmitted with ASAP: yourEngine.add

Verifying

Your application received messages. It is most probably notified by an ASAPChunkListener. You decided to let your application to sign their messages. Now, you need to verify those signatures. The transmitted message consists of three parts. They have to be split into sender, message and signature. Afterwards, the signature can be verified.

CharSequence sender = .. // 
byte[] yourMessage = ... // received message
// split message and signature
ByteArrayInputStream bais = new ByteArrayInputStream(yourMessage);
// read signer
String signer = ASAPSerialization.readCharSequenceParameter(bais);
// read message
byte[] message = ASAPSerialization.readByteArray(bais);
// read signature
byte[] signature = ASAPSerialization.readByteArray(bais);

if(ASAPCryptoAlgorithms.verify(message, signature, signer, basicCryptoParameters)) {
    // ok - your application message is verified
}

Encrypting

Setup security environment

Clone this wiki locally