Using PGP can be quite hard, even if you have a lot of experience with computers.
By the way encryption is what gives us privacy and permits us to safely transmit information
and for this reason it should be easy to use, for everyone.

PGP identity

When Keybase was launched it was mainly a wrapper for PGP commands
to encrypt and decrypt a message for a certain user, but it also introduced a very nice
chain of trust.

In Keybase it's possible to either generate a new PGP key or import an existing one
but the most important thing is being able to verify our own identity using multiple proofs.

Many of us have a personal blog, a Twitter or Facebook accounts, a GitHub account etc...
All these accounts combined together make our online identity.

Every Keybase account can be verified by other online identities. In Keybase
you don't just say "I'm Andrea Grandi, this is my PGP key...". In Keybase you
can link your existing online accounts to your Keybase account and show additional
proofs of your identity.

Unless an attacker controls all your social accounts, they cannot impersonate and verify
themselves as if they were you.

Once you are on Keybase, other users can look for you even using your GitHub or Twitter username
without having to know your email address or Keybase username. This concept can be
very useful in some situations, we will see it later.

Encrypted Filesystem

One of the first features launched by Keybase was their encrypted filesystem.
There is a virtual folder located at /keybase (on OSX/Linux or k:\keybase on Windows)
where you will find at least three other folders: public, private, team.

Public folders

Anything you place inside the /public folder can be accessed by any Keybase user and it's
automatically signed. Every user public folder/file can be accessed using their Keybase username,
like for example /keybase/public/andreagrandi/hello.txt but you can also use any other identity like
/keybase/public/[email protected]/hello.txt or /keybase/public/[email protected]/hello.txt

Note: This is very useful if you only know a person on Twitter (or GitHub etc...) and you want to
share a file with them (or send a message, as we will see later) but you don't follow each other
and you can't reach them privately.

This is a public folder example of one of the Keybase developers:

You can put whatever you want in these folders: your public PGP key, your official avatar,
your Signal fingerprint etc... the other users will access these files with the assurance they
haven't been changed by anyone else in the middle.

Note: please keep in mind that Keybase doesn't work like Dropbox or similar. Files are not
synced between your devices and Keybase servers. Files are streamed on demand, so you won't be able to access these files without a working Internet connection.

Private folders

Hey but... where is the encryption here?! Whatever you put inside your private
folder can only be read by you and only you. Not even Keybase employees can access the content of your files,
because they are encrypted before leaving your devices and decrypted on demand
when you want to access them.

Do you want to share files with anotheruser? No problem. Just create a file inside /keybase/private/andreagrandi,anotheruser
(the folder andreagrandi,anotheruser will implicitely exist already) and that file will only be readable by you and anotheruser.

Security and other information

Keybase employes only have access to: 1) your top level folder names (like: "andreagrandi,anotheruser"),
2) when and for how long you are reading/writing, 3) how much space you are using.

They won't be able to access the content of your files and not even the files or folders names.

Every user initially had 10GB quota available, but a few hints (including one of their recent screenshots)
say that now users have 250GB available to store their files.

You can even send a message to a person who is not on Keybase yet: if you send a message to
[email protected], when randomuser joins Keybase and verify their Twitter account, the message
will be encrypted for them and will be safely delivered.

Security

Keybase doesn't use PGP to encrypt chat or files. Transmitting the key across all devices
wouldn't be safe so each message is encrypted using the public key of every device connected
to the account.

Command line

Keybase works from the command line too. There is no need to use the graphic
client to send a message to another user, you can do something like this:

keybase chat send andreagrandi "Hello mate!"

You can integrate messages in any script and it's even available a JSON API:

Teams

Keybase has recently introduced Teams feature. The Chat becomes more similar to Slack, but with the difference that
only team members can read the content of messages and files: the server only knows about team names and users, nobody else can
access the content.

It's important to mention that in Keybase there aren't private channels like there are in Slack: if a team wants to have
channels accessible only from a restricted group of users, the admin needs to create a sub team. For example if you have a
team called keybaselovers you can create a sub team for admins only called keybaselovers.admins

Teams have a dedicated encrypter folder that you will find under /keybase/team/keybaselovers

At the moment the features available from the UI are quite limited and are only available from the command line. In the next
weeks these features will be available from the UI too. In the mean time you can have a look at the commandline help:

Add a user to a Team

Git

Sometimes we have the need to store private information in a safe way and we want to be sure that nobody else is
able to access these information.

Latest feature that has been added to Keybase is encrypted Git repositories. They are like normal GitHub
repositories, but their content is stored in a safer way.

Privacy and Security

What is the difference with GitHub private repositories? In GitHub a private repository is used to store information that
only our account can access, but the files are accessible in plain text by GitHub employees. With encrypted Git repositories
instead, the information are encrypted before they leave our device and they are stored encrypted. Nobody, without having our
private key can read them, not even Keybase employees.

Teams and Quota

Encrypted Git repositories are of course available for teams too. Creating a team repository, it will be available to
all the members of the team.

Both teams and single users have 100GB of space available (which is separate from Folders quota).

Usage

If I create my personal repository called documents all I have to do to clone it and use it is:

git clone keybase://private/andreagrandi/documents

and I can use it as a normal git repository. Every time I commit and push something, the content will be signed and encrypted
and only available to the repository owner (which is me) or to the whole team if it's a team repository.

Conclusion

Keybase is still in continuous development but it already offers a few interesting features which can help people
in their every day life. I strongly advise anyone to get an account, play with the available features and report any bug
so the developers will be able to fix them and build an even better product. I can't wait to see the features they will
announce in the next months!

I've recently bought a YubiKey 4 and
decided to use it for GnuPG too, other than using it as hardware 2FA.

I've also decided to make my GnuPG configuration much more safe, generating the master key
on an offline computer (in my case a simple RaspberryPi not connected to Internet) and generating a subkey
that will be moved to my YubiKey.

Disclaimer

Always think about what your threat model is before deciding something is 100% safe for you.
I'm not claiming this setup/configuration is bullet proof. If you want to protect your GnuPG key from most of the hackers,
keyloggers and if you want to use it on different computers without ever compromising your secret key, this setup
can be what you are looking for. If you think you may be victim of a targeted state sponsored attack, I'm not sure this
setup could be enough.

Why keeping offline the master key?

If you only use your master key on a computer that never connects to Internet (I reckon you will want to update/patch it
from time to time, that's why we are going to keep the master key on an external USB key) you are at least safe from remote attacks.

Why using subkeys?

Your GnuPG master key is also your "identity" among every PGP user. If you loose your master key or if your key is compromised
you need to rebuild your identity and reputation from scratch. Instead, if a subkey is compromised, you can revoke the subkey (using your
master key) and generate a new subkey.

How a YubiKey makes things safer?

If you always use your subkey from a YubiKey, it's very unlikely that your
private key can be stolen: it's impossible to read it from the YubiKey and if you loose your YubiKey
or if it's physically stolen, the attacker will still need your passphrase and your YubiKey PIN.

Requirements

2 USB keys (in theory you only need one, but I strongly suggest you have another one as backup)

1 offline computer (a simple RaspberryPi with no Internet connection will be fine)

Initial setup

From now on, I will assume that you have prepared a computer for offline use (in my case I'm using a RaspberryPi 2 with
Raspbian) and you will type the next commands there and only there.

Plug one of the USB key (you can format it with VFAT for simplicity) in the offline computer and wait for the system to mount it.
At this point it should be mounted in a path like this: /media/AABB-BAAC

Second disclaimer

If you think your threat model doesn't include someone can hack your computer from remote,
you can ignore my advice and type these commands on your main laptop (at your own risk).

Note

For my own convenience, to write this tutorial I reproduced all these steps on my MacBook because it was easier to copy/paste
commands and outputs but I've tested it with the exact setup I'm describing, and it
should be compatible with OSX and Linux.
When you see something has been masked it's just to hide (from spam) things like my email or to protect the serial number
of my YubiKey. Last but not least, the output shown here could not match exactly the one you get on your own PC and this also
depends on the GnuPG version you are using.

Generating the master key

The master key must be generated using the advanced mode, because by default when a new master key is generated, also a new subkey
is created with all the capabilities (Authentication + Signing + Encryption), while we want something different.

Note: PGP keys up to 4096 bits are only supported in YubiKey 4 models. If you have a YubiKey NEO you must use
a 2048 bits key because it's the maximum size supported. Here you will create a PGP key with only
the Authentication capability. If your GnuPG version doesn't allow this, choose "sign only", just don't
create the encryption capability at this time.

Note: please remember to save your passphrase in a safe place. Choose something you
can remember because you will need it every time you need to sign, encrypt or decrypt something.

Creating a revocation certificate

It's very important to create a revocation certificate to be used if and when
in the future you want to change your master key and revoke the existing one:

[email protected]:~$ gpg --gen-revoke 2240402E > 2240402E-revocation-certificate.asc
sec 4096R/2240402E 2017-09-25 Andrea Grandi <[email protected]>
Create a revocation certificate for this key? (y/N) y
Please select the reason for the revocation:
0 = No reason specified
1 = Key has been compromised
2 = Key is superseded
3 = Key is no longer used
Q = Cancel
(Probably you want to select 1 here)
Your decision? 3
Enter an optional description; end it with an empty line:
>
Reason for revocation: Key is no longer used
(No description given)
Is this okay? (y/N) y
You need a passphrase to unlock the secret key for
user: "Andrea Grandi <[email protected]>"
4096-bit RSA key, ID 2240402E, created 2017-09-25
ASCII armored output forced.
Revocation certificate created.
Please move it to a medium which you can hide away; if Mallory gets
access to this certificate he can use it to make your key unusable.
It is smart to print this certificate and store it away, just in case
your media become unreadable. But have some caution: The print system of
your machine might store the data and make it available to others!

Creating Encryption subkey

To create a subkey we need to edit the existing key (please note that 2240402E
is the last 8 chars from the fingerprint of the previously generated master key)
and specify we want to create an Encryption only key.

Note: this backup includes both the secret master key and the secret subkey.
Please remember to save a backup of this key on a couple of separate USB keys: you will need
this keys to generate future subkeys and/or to revoke the existing ones.

Programming the YubiKey with all GnuPG keys

We have previously created the master key and the encryption subkey. Now we will
create the authentication and signing keys directly on the YubiKey (we don't
need to have a copy of these keys) and we will move the secret encryption key
to the YubiKey.

Check private keys

When we check the private keys we should see that one key is still local, marked as sec (it's
the private key of the master key), while three other keys are marked as ssb>
which means they have been moved to the YubiKey:

Import back secret keys from backup (only for multiple YubiKeys)

As previously said, when we write the encryption subkey to the YubiKey, the key
is moved and not just copied, so we need to import back the secret key into
the keyring. It's important to have a backup of the subkey too, not because we need it
in case the key is compromised etc... but because we need it in case we want to write
multiple YubiKeys with the same encryption key, so that we have a backup key to use.

Change YubiKey PINs and complete configuration

Every YubiKey is sold with a certain default configuration: there is a user PIN
that is required every time we need to use the key to sign/decrypt something (in addition
to our passphrase) and there is an admin PIN that is required every time we change
certain settings on the YubiKey.

Note: when you want to use your YubiKey on any computer (for example your work laptop)
you need to at least import your public PGP key into the keyring. If the key is not
read automatically, you may need to give it a refresh using this command:

Careful with PINs

Please remember that you can only digit a wrong user PIN for a maximum of three times.
After three time you will need to edit the YubiKey (with gpg --card-edit) become admin
and use the unblock PIN option. If you digit the wrong admin PIN for three time, you will have
to follow a quite complicated procedure (explained at this address: https://developers.yubico.com/ykneo-openpgp/ResetApplet.html)
and your YubiKey will be reset with factory settings, deleting your PGP keys from it.

References

To write this tutorial I originally followed other articles online. The main ones are:

Amazon Association disclaimer

I'm trying a little experiment with the Amazon Association program. Basically, if you click
on any of the YubiKey links and decide to buy it, I will get a little commission from it.
I've never tried this before and I've no idea if it works or not. I'm writing this here just for the
sake of transparency.

When we need to create an EC2 resource on AWS using Terraform, we need to specify the AMI id to get the correct image.
The id is not easy to memorise and it changes depending on the zone we are working one. On every new release the id changes again.
So, how can we be sure to get the correct ID for our region, of the latest image available for a given Linux distribution?

Getting latest Ubuntu AMI id

In this example I will show how to get the ID for the latest version of Ubuntu 16.04 server, for the London region and create an EC2 instance using that ID.

In the previous
part
of the tutorial we implemented details management, relations
between models, nested APIs and a different level of permissions.
Our API is basically complete but it is working properly? Is the source
code free of bugs? Would you feel confident to refactor the code without
breaking something? The answer to all our question is probably no. I
can't be sure if the code behaves properly nor I would feel confident
refactoring anything without having some tests coverage.

As I mentioned previously, we should have written tests since the
beginning, but I really didn't want to mix too many concepts together
and I wanted to let the user concentrate on the Rest Framework instead.

Django has an integrated test runner but my personal choice is to use
pytest, so as first thing let's
install the needed libraries:

pip install pytest pytest-django

As long as we respect a minimum of conventions (test files must start
with test_ prefix), tests can be placed anywhere in the code. My
advice is to put them all together in a separate folder and divide them
according to app names. In our case we are going to create a folder
named "tests" at the same level of manage.py file. Inside this
folder we need to create a __init__.py file and another folder
called catalog with an additional __init__.py inside. Now,
still at the same level of manage.py create a file called
pytest.ini with this content:

[pytest]DJANGO_SETTINGS_MODULE=drftutorial.settings

Are you feeling confused? No problem. You can checkout the source code
containing these changes.

git checkout tutorial-1.15

You can check if you have done everything correctly going inside the
drftutorial folder (the one containing manage.py) and launching
pytest. If you see something like this, you did your changes
correctly:

Writing the first test

To begin with, I will show you how to write a simple test that will
verify if the API can return the products list. If you remember we
implemented this API in the first part of the tutorial. First of all
create a file called test_views.py under the folder
drftutorial/tests/catalog/ and add this code:

before being able to run this test we need to change a little thing in
the catalog/urls.py file, something we should have done since the
beginning. Please change the first url in this way, adding the name
parameter:

Explaining the test code

When we implement a test, the first thing to do is to create a
test_* file and import the minimum necessary to write a test class
and method. Each test class must inherit from APITestCase and have a
name that start with Test, like TestProductList. Since we use
pytest, we need to mark our method
with @pytest.mark.django_db decorator, to tell the test suite our
code will explicitly access the database. We are going to use the client object
that is integrated in APITestCase to perform the request. Before doing that we
first get the local url using Django's reverse function. At this point
we do the call using the client:

We check that our API returns the 200 status code and that in the returned
JSON there are 8 elements.

It's normally a good practice to create test data inside the tests, but in our case
we previously created a data migration that creates test data. Migrations are
run every time we run tests so when we call our API, the data will be already there.

Wrapping up

I've written a few tests
for all the views we have implemented until now and they are available
if you checkout this version of the code:

git checkout tutorial-1.17

I've only tested the views but it would be nice to test even the permission class, for example.
Please remember to write your tests first, if possible: implementing the code will be much more natural
once the tests are already in place.