-
Notifications
You must be signed in to change notification settings - Fork 7
Getting started
This is a step-by-step introduction to help you get started using the secon-tool API.
In order to exchange messages using the SECON library you need to setup a few things first:
To be able to sign and decrypt messages you need to create a keystore containing all of your personal key pairs (private key and certificate). This can be done using tools like keytool (included in the JDK) or "KeyStore Explorer".
keytool -keystore my_keystore.p12 -storetype PKCS12 -storepass secret -genkey -alias foo -dname CN="Foo Ltd." -keyalg rsa -keysize 4096 -sigalg rsassa-pss -v
NOTE: All keypair entries in the keystore should share the same password since in order to work properly.
To be able to encrypt and verify messages for communication partners you need to provide the public keys of all your communication partners. This can be done in two ways:
a) Setup another keystore containing the public keys for communication partners
Again, use keytool to import the public keys
keytool -keystore partners_keystore.p12 -storetype PKCS12 -storepass secret -genkey -alias bar -dname CN="Bar Ltd." -keyalg rsa -keysize 4096 -sigalg rsassa-pss -v
b) Setup an LDAP directory containing all public keys
ITSG Trust Center publishes all public keys of communication partners on it's website. These keys can be imported into an LDAP directory structure. The secon-tool can use this LDAP directory to lookup the public keys of recipients.
To send a messsage perform the following steps:
1. Create a "java.security.KeyStore" instance containing your own key pairs:
KeyStore myOwnKeys = SECON.keyStore(() -> new FileInputStream("my_keystore.p12"), "secret"::toCharArray);
2. Create an instance of de.tk.opensource.secon.Identity
representing yourself as the message sender. Along with the keystore instance you need to pass the alias of the key that will be used to sign your message ("foo" in this case).
Identity me = SECON.identity(myOwnKeys, "foo", "secret"::toCharArray);
3. Setup the Directory object containing all public keys of communication partners
a) using an existing LDAP server
Directory dir = SECON.directory(URI.create("ldap://127.0.0.1"));
b) using another keystore instance
Directory publicKeyDirectory = SECON.directory(SECON.keyStore(() -> new FileInputStream("partners_keystore.p12"), "secret"::toCharArray));
4. Finally, create a de.tk.opensource.secon.Subscriber
object for yourself (the sender) specifying the the identity object created in step 2 and the directory object from step 3(a or b).
Subscriber sender = subscriber(me, publicKeyDirectory);
The subscriber can then be used to create a new message for a selected recipient. The recipient can be identified by
a) it's identifier in the LDAP directory (step 3.a)
or
b) the alias corresponding to the public key in the keystore (step 3.b)
Creating a message is done by copying the input data to the resulting output stream:
ByteArrayInputStream input = new ByteArrayInputStream("Hello bar, how are you?".getBytes());`
try(FileOutputStream output = new FileOutputStream("out.cms")) {
SECON.copy(() -> input, sender.signAndEncryptTo(() -> output, "bar"));
}
The secon-tool uses streaming for I/O to avoid keeping large messages in memory. This allows for efficient processing of large messages.
Complete Example
KeyStore myOwnKeys = SECON.keyStore(() -> new FileInputStream("my_keystore.p12"), "secret"::toCharArray);
// sender's identity using key alias "foo" from the key store
Identity me = SECON.identity(myOwnKeys, "foo", "secret"::toCharArray);
//a) Directory using keystore with public keys
Directory publicKeyDirectory =
directory(SECON.keyStore(() -> new FileInputStream("partners_keystore.p12"), "secret"::toCharArray));
//b) Directory using LDAP
//Directory dir = directory(URI.create("ldap://127.0.0.1"));
// subscriber for sender side
Subscriber sender = subscriber(me, publicKeyDirectory);
// write a message to recipient with key alias "bar"
ByteArrayInputStream input = new ByteArrayInputStream("Hello bar, how are you?".getBytes());
try(FileOutputStream output = new FileOutputStream("out.cms")) {
SECON.copy(() -> input, sender.signAndEncryptTo(() -> output, "bar"));
}
In order to decrypt a message sent to you from a communication partner you can use the same objects (KeyStore, Identity, Subscriber) created above in the section for sending a message. For decryption the secon-tool will pick the private key from the keystore that matches the public key the sender used to encrypt the message. If such a key can't be found a CertificateNotFoundException
will be raised.
Decrypting a message contained in a file "out.cms":
// decrypt using subscriber object
Subscriber receiver = subscriber(me, publicKeyDirectory);
// decrypt (and verify) message contained in "out.cms" to a text file "plaintext.txt"
try(FileOutputStream plaintext = new FileOutputStream("plaintext.txt")) {
SECON.copy(receiver.decryptAndVerifyFrom(() -> new FileInputStream("out.cms")), () -> plaintext);
}
NOTE: make sure all output streams are properly closed (use a try-with-resources block) to avoid incomplete processing of messages.