1. Staff Advice

Tip

*Above all other pieces of advice, this may be our most important

one:* spend a good amount of time designing your solution (and analyzing its security) before starting the implementation. Designing a secure solution is significantly harder than implementing the project, and if you work out most of the issues in your design before starting to program, you’ll avoid having to reimplement things if you discover that there are security issues after you’ve started to write code.

If you do the design phase right, you will likely find writing your design document the most difficult aspect of this project—implementation might still take some time since you might need to debug things, but it will be much easier to implement the client once you’re confident in your outlined design.

This project is challenging. If you’re having trouble coming up

with a design that covers all of the requirements, don’t worry—one of the main goals of this project is to give you the “real-life” experience and challenge of having to build a non-trivial secure system yourself.

There are many different ways to implement this project, and the specification involves many elements whose implementation is highly-dependent on your overall design. This project is designed to give you a chance to do some critical thinking about security design in a broad sense and get hands on experience with subtleties in applied cryptography design. We encourage you to do lots of brainstorming with your partner, and consider many possible designs.

In designing your system, you may find the following pieces of advice helpful:

  • Don’t get too distracted by the stencil code when you’re early in the project. Make sure you spend most of your initial time focusing on the design before digging into the stencil code. For an overview of how to get started on the design, see the first project gearup.

  • Security should be thought of as a property of a design, not as a feature. If you approach the problem by first designing a service, and then afterwards adding security, your design will be complicated, and likely quite insecure.[1] Instead, you should aim to have security drive what design choices you make throughout the process—find designs that naturally lend themselves to being secure. Finding and choosing a design that leaves you with a manageable set of potential vulnerabilities is subjective, so we recommend you spend much time on this topic discussing with your partner.

  • Complexity is the enemy of security. The simpler your design is, the easier it will be for you to reason about its behavior, and the less likely it will be to behave in surprising, insecure ways.[2]

  • This project’s information flow model is slightly different from what we’ve seen in the past—instead of having a trusted server consuming untrusted client input, you’re implementing a trusted client that operates on untrusted server data. This can be initially difficult to wrap your head around at first, but the principles are still the same—you need some mechanisms on the trusted side of the implementation to move data from the untrusted domain to a trusted domain.

  • If you’re having trouble coming up with a design, we recommend you ignore the sharing aspects of the problem first and come up with a design that works for this simplified scenario. After that, you may need to rework some things around to get sharing to work, but it should be simpler to come up with a fully-fledged design once you have a good understanding of how you can implement file confidentiality and integrity on its own.

  • Don’t forget that the adversary is adaptive (see Threat Model). You should consider how this impacts different aspects of your system, such as key management.

  • Avoid dangerous design patterns such as reusing the same key for multiple purposes (i.e. encryption, authentication, key derivation, etc.) and authenticate-then-encrypt / decrypt-then-verify. These often lead to subtle vulnerabilities. We test for those and treat any instance of them as a breach of confidentiality and integrity.