An Introduction to Our Cryptography

The PKC Security team believes strongly in transparency. This page is intended to make sure you, as the user, know exactly what we do and do not encrypt, when it comes to the information with which you are trusting us. We believe that the best security comes from informed, caring, and empowered users. You are trusting us with your most personal information, and we want you to feel like Balboa is built on nothing less than the most convenient, most secure, and fastest cryptography currently being offered. If for some reason it isn't, we want to have an informed, technical debate on how to deliver what NGO field staff need to keep advancing their missions. Our ego and intellectual property are unequivocably second to you confidently promoting well-being for those to whom you are called.

If you have any questions, comments, or concerns, please contact us any time at We don't bite, despite cryptographers being famous for orneriness. Thank you for your trust!

Cryptographic Primitives
We use the following primitives as building blocks for a wide variety of cryptographic applications (which we will discuss in detail below) within Balboa:
  • PRNG ⋅ crypto.getRandomValues(...)
  • PRF ⋅ SHA-3 (i.e. Keccak)
  • AEAD ⋅ ChaCha20 with Poly1305
  • PBKDF ⋅ Scrypt
  • DH ⋅ Curve25519
Account Creation

Balboa users are required to register with a valid email address (which is confirmed before the account is created) and password. As an end-to-end encrypted application, user security is tied tightly to password strength. Passwords can contain any sequence of 10 or more characters. The max length is 256 characters. We strongly recommend users choose a word-based password: namely a sequence of 6 or more random words (or a longer, unique sentence or phrase). We have absolutely no way to reset your password if you lose it, but we do allow users to elect their own Trusted Administrator within the app. A Trusted Administrator is your secret-keeper: they can reset your password, and access your account.

Account Creation Protocol
  • A new user generates a keypair, Kkp, consisting of a public and secret key using Curve25519 crypto_box_keypair(), and a shared secret generated from the Curve25519 public and secret keys. Randomness for keypair generation is taken from the PRNG with crypto.getRandomValues() (or msCrypto.getRandomValues() for IE)
  • The user chooses a password to safeguard Kkp. We mandate a strong password of at least 10 or more characters.
  • A 256-bit ChaCha20 symmetric key, Kpbkdf, is derived from PBKDF(password, random_salt), where Scrypt is used with N = 15, r = 8, and p = 1 and the salt is generated using 256-bits of output from the PRNG.
  • The encrypted and MAC'd keypair is generated via Epbkdf(Kkp), using ChaCha20-Poly1305.
  • A verifier is calculated as PRF(Kpbkdf).
  • A hashed verifier is calculated as PRF(PRF(Kpbkdf)).
  • The user then sends the following information to the server:
    1. The Curve25519 public key.
    2. The 256-bit, randomly generated salt.
    3. The encrypted and MAC'd keypair
    4. The hashed verifier
When logging in, the following authentication steps are performed:
  1. The user sends his or her email to the server.
  2. The server responds with the user's salt.
  3. The user calculates his or her verifier and sends it to the server.
  4. The server calculates the hashed verifier from the transmitted verifier. If the transmitted hashed verifier is equivalent to the stored hashed verifier from the account creation step, the user is granted a WebSocket ticket. If multifactor authentication is enabled, the user must provide an additional code, which is transmitted and compared server-side before granting a WebSocket ticket.
  5. The WebSocket ticket is spent by passing this ticket in the URL, which, if valid, will open a WebSocket with Balboa.
  6. Once the WebSocket is open, the encrypted and MAC'd keypair is sent to the client for decryption within their browser only. The plaintext is never sent to the server. The client can now interact with Balboa.
End-to-end Encryption

Many "secure" systems marketed today claim to be end-to-end encrypted: By this, they mean the data is protected between your client and the server. Balboa is better. All content and metadata, except where noted below, is encrypted on the client using client-generated keys before it reaches Balboa’s servers. In this way Balboa cannot read the data entrusted into our care. Be advised that Balboa does not strive to make anonymity a hard property of its system: If this is part of your threat model, please consider technologies like Tor. The following chart gives a quick overview of which parts of our system are encrypted and which are not:

Personal Information
Content Encrypted Unencrypted
Name (not required) X
Phone Number (not required) X
Password X
Keypair X
Labels X
Contact List X
Team Member Emails X
Account Balance X
Content Encrypted Unencrypted
File MessagesX
File LabelsX
File RecipientsX
File SizesX
File Send DatesX
Content Encrypted Unencrypted
Direct (One-on-one) MessagesX
Room MessagesX
Room TitlesX
Files shared within Rooms or Direct MessagesX
Room MembersX
Room Message TimesX
How We Encrypt Files and Chats

All file data is encrypted using a 256-bit symmetric key and 256-bit nonce, using ChaCha20-Poly1305. ChaCha20 state is constructed with a 64-bit nonce and 64-bit counter construction, as opposed to the IETF variant, which uses a 92-bit nonce and 32-bit counter. Balboa hopes to support files larger than 256GB soon, which requires more bits for the counter. We, therefore, use the more common implementation of ChaCha20. In order to prevent reusing a key and a nonce pair for different plaintexts (which is non-negligible given a random 64-bit nonce), we use SHA-3 to hash the key, nonce combo, and take the first 256-bits of SHA-3 output for the key, and subsequent 64-bits for a nonce. output = PRF(key || nonce) key = output[0..256] nonce = output[256..320]

The final 16 bytes of the ChaCha20 stream after the plaintext has been xor'd is used to initialize Poly1305. Poly1305 is then used to MAC the ciphertext and nonce. MACstream[n..n+16](message[0..n]), where stream = Ekey,nonce(Ø[0..]) and Ø[0..n] is an n-length buffer of zeros.

File metadata, such as filename, corresponding labels, as well as a 256-bit secret file key per 5MB chunk, are all encrypted using a precomputed key generated from the sharer’s secret key and the recipient’s public key (sometimes the sharer and recipient are yourself). EDH(Psharer, precipient)(file_keyi) where the file plaintext is encrypted using Efile_key0(FILE[0..5M]) || Efile_key1(FILE[5M..10M])... An encrypted file blob is its Poly1305 MAC, nonce, and ciphertext and is not stored with Balboa, but rather is sent to Amazon S3.

Chats are encrypted exactly like files, using a unique nonce per message. A chat key is per Room and per Direct Message recipient and is not visible to the backend. All new recipients added to a Room or invited to a Direct Message session are given the chat key after it is encrypted using the precomputed key of the sharer's private key and recipient's public key. We are working at this time to integrate an even better protocol, similar to the Axolotl Rachet, into Balboa. This page will be amended to reflect that work's completion, and, we look forward to the community's feedback.

Key Distribution

When a user needs to share encrypted data with another user, they first check their Trust on First Use (TOFU) public key store for the public key of the intended recipient. This store is encrypted and MAC'd when stored server-side. If this is the first time they are contacting the user, they request the public key from Balboa. In order to deter MITM attacks, where the keyserver is forced to serve up an attacker's public key in lieu of the recipient's, users can verify key fingerprints before sending files. We are working on implementing this more fully and are considering more user-friendly methods, but for now, to verify a fingerprint, go to the "Files View", and open the "Send Panel". Enter a Balboa user's email into the field. Once the contact is entered, hover over the contact (a golden key will appear) and double-click. You will see the fingerprint. Your friend can find their own public key in Settings, under "Advanced Security Settings."

Front-end and Back-end Transport Security

Balboa uses WebSockets over TLS, and all requests are served over HTTPS. TLS to our main app domain uses ECDHE, giving us Perfect Forward Secrecy (PFS) for websocket messages between the client and the server. Balboa also uses a strict Content Security Policy to prevent cross site scripting. Balboa also includes HSTS headers, and we have submitted our domain to the HSTS Preload list, to guarantee attacks like sslstrip are not trivially executable. Balboa also uses HPKP (key pinning) to guarantee our SSL certificate signature is cached locally to prevent malicious or compromised certificate authorities from mimicking Balboa.

A mobile application (March 2016) and desktop application (Summer 2016) will contain pins for any Balboa public keys to prevent any TOFU requirements. Until then, we would like to caution users traveling to locations with highly untrustworthy connectivity first to visit Balboa in a trusted location to cache these values within his or her browser.

All inter-service communication on Balboa’s backplane is encrypted with ZeroTier. ZeroTier provides encryption between Balboa’s microservice endpoints, and has the additional benefit of flattening our network topology which allows fast and reliable hot-swapping.

Begin to protect your field staff today, with no credit card required.

Try BALBOA now, with no strings attached, for one month.

PKC Security
8092 Warner Ave
Huntington Beach, CA 92647

+1 714-845-6341