Session Encryption
Because Public Key Cryptography is a slow and expensive and better suited to small amounts of data. Keyczar has a built in API that mixes asymmetric and symmetric encryption. It requires an asymmetric key set as show in Keyczar Public/Private Encryption and uses that the public key to encrypt a random AES key and random HMAC key stored as SessionMaterial
and then encrypts your plaintext with that AES key, so that if you provide that SessionMaterial
with the private key you can decrypt the plaintext.
So for encryption and creating the session
WebBase64 sessionMaterial;
WebBase64 cipherText;
using(var encrypter = new Encrypter("path_to_public_key_set"))
using(var sessionCrypter = new SessionCrypter(encrypter))
{
sessionMaterial =sessionCrypter.SessionMaterial;
cipherText = sessionCrypter.Encrypt(plaintext);
}
Note: If you are wondering what a WebBase64 is, it's a static type for a web safe base64 encoded string.
Then to decrypt from a session
using(var crypter = new Crypter("path_to_private_key_set"))
using(var sessionCrypter = new SessionCrypter(crypter, sessionMaterial))
{
return sessionCrypter.Decrypt(cipherText);
}
However, if you don't close the sessionCrypter, you can actually encrypt/decrypt from the session starter or the session recipient.
Signing the session is also available to authenticate the sender, however the encryption/decryption then becomes one way. The sender can only encrypt and the recipient can only decrypt.
Sender
WebBase64 sessionMaterial;
WebBase64 cipherText;
using(var encrypter = new Encrypter("path_to_public_crypt_key_set"))
using(var signer = new AttachedSigner("path_to_private_sign_key_set"))
using(var sessionCrypter = new SessionCrypter(encrypter, signer))
{
sessionMaterial =sessionCrypter.SessionMaterial;
cipherText = sessionCrypter.Encrypt(plaintext);
}
Then to decrypt from a session
using(var crypter = new Crypter("path_to_private_crypt_key_set"))
using(var verifier = new AttachedVerifier("path_to_public_sign_key_set"))
using(var sessionCrypter = new SessionCrypter(crypter, sessionMaterial, verifier))
{
return sessionCrypter.Decrypt(cipherText);
}
Note: This is compatible with the SignedSessionEncrypter/SignedSessionDecrypter
of the Java/Python/C++ versions.
The C# api also has an alternative format for packing the symmetric key that makes the key type flexible.
So for encryption and creating the session
WebBase64 sessionMaterial;
WebBase64 cipherText;
using(var encrypter = new Encrypter("path_to_public_key_set"))
using(var sessionCrypter = new SessionCrypter(encrypter, symmetricKeyType: KeyType.AES_AEAD, keyPacker: new BsonSessionKeyPacker()))
{
sessionMaterial =sessionCrypter.SessionMaterial;
cipherText = sessionCrypter.Encrypt(plaintext);
}
Then to decrypt from a session
using(var crypter = new Crypter("path_to_private_key_set"))
using(var sessionCrypter = new SessionCrypter(crypter, sessionMaterial, keyPacker: new BsonSessionKeyPacker()))
{
return sessionCrypter.Decrypt(cipherText);
}
Note: you can also add a signer and verifier to a session using a BsonSessionKeyPacker
, it provides an extra security measure of signing the session material in addition to the cipher text, but this is only compatible with the C# version of Keyczar.