Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Encrypted Logging for WPAndroid #10698

Closed
jkmassel opened this issue Oct 25, 2019 · 4 comments
Closed

Implement Encrypted Logging for WPAndroid #10698

jkmassel opened this issue Oct 25, 2019 · 4 comments

Comments

@jkmassel
Copy link
Contributor

jkmassel commented Oct 25, 2019

Background

One of our long-term goals is to enable encrypted logging across any applications that use it. These logs can be used to diagnose issues in our applications, and are meant to be used in two places:

  1. Crash logs are associated with crash reports – they'll show up as a field on a Sentry event – from there, a developer can view them in order to see what the user was doing in a session prior to a crash.
  2. Crash logs are appended to support requests – when the request is sent, the log is sent along with it. This enables the support folks to have an idea of what the person is doing, and see any error messages that might be popping up in the log.

This data is highly sensitive – it can contain a list of every site the user is logged into, as well as a list of all of the reader activity during the current session. These details must be kept safe and private.

Current State

Encrypted logging has already been implemented on iOS. There are a few implementation details to be aware of:

  • It uses libsodium to handle encryption and decryption. This library was chosen because it's cross platform (including being built into PHP, so decryption on the server is trivially simple and fast), so we have to do very little implementation ourselves. Also, it's better than anything we could've built ourselves – rule Menu Drawer Item refactor #1 of encryption is don't build your own encryption.

  • On iOS, most of the encryption logic has been implemented in a library we use called Tracks. Tracks handles all of our logging and telemetry needs, and has recently also taken on Crash Logging. It should contain enough of the log encryption functionality to allow calling it from multiple other apps with nearly no repeated code.

  • The implementation uses an xchacha20poly1305 stream to asymmetrically encrypt the message.

  • Encrypted logs have the following format:

  {
    "keyedWith": "v1",	                // this is hard coded by the log encoder
    "encryptedKey": "$key_as_base_64",	// The encrypted AES key
    "header": "base_64_encoded_header",	// The xchacha20poly1305 stream header
    "messages": []			// the stream elements, base-64 encoded
  }

More detail on the implementation are below.

Implementation Details

Encryption Scheme

Encrypted logs have three main fields you'll need to deal with, and they're in order of when you're most likely to need to deal with them.

Encrypted Key

In order to encrypt messages, xchacha20poly1305 requires an encryption key. This key is uniquely generated for each encrypted log. In order to keep this (and thus the rest of the message) a secret, it's encrypted using a libsodium sealed box. The public key for this sealed box is not a secret. For now, we'll use K0y2oQ++gEN00S4CbCH3IYoBIxVF6H86Wz4wi2t2C3M= as the public key. The server has the private key needed to decrypt this log's encrypted key.

Header

The header is provided by xchacha20poly1305 and is needed to initialize decryption of the remainder of the message. Info on how this encryption process and decryption process works can be found here. The header is already encrypted when you call xchacha20poly1305_init_push, so there's no need to do any further processing besides base64 encoding it in the JSON.

Messages

Because these log files can be arbitrarily long, storing them as a JSON array makes it possible to encode and decode log files in a really memory-efficient way. Each element in the messages array is a single line from the log, encrypted using secretstream_xchacha20poly1305_push and encoded with base64. The last element in the array should be an encrypted and encoded empty string, with the FINAL tag attached.

Testing

To test this functionality, you can upload the file generated by your code using curl, as follows:

curl --data "@file.json" https://log-encryption-testing.herokuapp.com

For now, it'll just send back the decrypted log.

@ravenstewart
Copy link

ravenstewart commented Nov 4, 2019

I began work on this task over the weekend.

@stale
Copy link

stale bot commented Nov 7, 2020

This issue has been marked as stale because:

  • It has been inactive for the past year.
  • It isn't in a project or a milestone.
  • It hasn’t been labeled [Pri] Blocker, [Pri] High, or good first issue.

Please comment with an update if you believe this issue is still valid or if it can be closed. This issue will also be reviewed for validity and priority during regularly scheduled triage sessions.

@stale stale bot added the [Status] Stale label Nov 7, 2020
@wzieba
Copy link
Contributor

wzieba commented Feb 22, 2021

@oguzkocer @jkmassel 👋

Does this PR close this issue? #12571

@stale stale bot removed the [Status] Stale label Feb 22, 2021
@oguzkocer
Copy link
Contributor

@wzieba Yes it does, thanks for noticing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants