Archive for the ‘Security’ Category

My GPG Config

Tuesday, November 28th, 2017


Some notes about my current setup for GPG/PGP.

I’m currently using GnuPG: and in particular GPG4Win.

Portable mode

As usual, I like portable installs and GPG is no exception. I’ve uncompressed it in my tools folder (synchronized across my machines). By itself, the tool is portable, maybe Kleopatra isn’t but I don’t care too much.

By default, Gpg4win installs in two locations:

  • Gpg4win: C:\Program Files (x86)\Gpg4win
  • GnuPG: C:\Program Files (x86)\GnuPG

Bash profile

Here’s how my bash profile is configured to have GPG tools available:

# where the tool is installed
export GPG4WIN_HOME=$TOOLS_HOME/Gpg4Win_3.0.1

append_to_path $GPG_HOME
append_to_path $GPG_HOME/bin
append_to_path $KLEOPATRA_HOME/bin_64
append_to_path $KLEOPATRA_HOME/bin

# where it puts its files and looks for its configuration
export GNUPGHOME=$HOME/.gnupg

# create it otherwise it complains
mkdir -p `echo $GNUPGHOME`
alias gpg='gpg.exe'
alias pgp='gpg' # who cares ;-)
alias kleopatra='kleopatra.exe'

GPG configuration

Here’s my current GPG configuration (~/.gnupg/gpg.conf). I’ve removed comments for stuff I don’t use for clarity, although I like to keep those in my actual configs):

# get rid of the copyright notice

# key server
keyserver hkp://

# Ensure that stronger secure hash algorithms are used by default
default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAMELLIA256 CAMELLIA192 CAMELLIA128 TWOFISH CAST5 ZLIB BZIP2 ZIP Uncompressed
personal-digest-preferences SHA512
cert-digest-algo SHA512
# Enable the passphrase agent
# Avoid locking files

# Armor when exporting
# Keyserver options
keyserver-options auto-key-retrieve include-subkeys honor-keyserver-url honor-pka-record
# Import/export options
import-options import-clean
export-options export-clean

# Don't use key ids are those are unsafe (both short and long!)
keyid-format none

With this configuration, I’ve forced the usage of stronger secure hash algorithms by default and also disabled key ids (short & long) since those are insecure. There’s nothing much to it.

How I generated my keys

First of all, I didn’t reinvent the wheel, I’ve mostly applied what Alex Cabal has described here, so thanks to him!

You might ask “Why not a simple key that does it all?”. Because in general, mixing signing and encryption keys is not a good idea, management & security wise. Firstly, different key types have different lifecycles. Secondly, it might just not be safe to do so.

Also, without this setup, if the keys I use on a daily bases were to be compromised, I wouldn’t have any other choice but to re-create everything from scratch (i.e., new identity!). With the configuration below I can just revoke a specific sub-key and create a new one, while keeping my identity.

Here’s the whole shabang.

Create the keypair

First of all, create the key:

gpg --gen-key

Settings to use:

  • Kind of key: (1) RSA and RSA
  • Key size: 4096 (longer = safer?)
  • Valid for: 0 (never expires)
  • mail: [email protected]

When selecting the passphrase, use a tool like Keepass, don’t choose the passphrase yourself, you’re not smart enough ;-).

Set strong hash preferences on the keypair

Just to make sure:

gpg --edit-key [email protected]
gpg> setpref SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAMELLIA256 CAMELLIA192 CAMELLIA128 TWOFISH CAST5 ZLIB BZIP2 ZIP Uncompressed
gpg> save

Add a signing sub-key

Next, create a signing sub-key for code signing:

gpg --edit-key [email protected]
gpg> addkey
gpg> save


  • Key type: (4) RSA (sign only)
  • Key size: 4096 (longer = safer?)
  • Valid for: 0 (never expires)
  • mail: [email protected]

Add an authentication sub-key

Next, create an authentication sub-key for SSH authentication:

gpg --expert --edit-key [email protected]


  • (8) RSA (set your own capabilities)
  • S: disable sign
  • E: disable encrypt
  • A: enable authenticate
  • –> now you must see “Currently allowed actions: Authenticate”
  • Q: finished
  • Key size: 4096
  • Expires: today + 365 days

Create a revocation certificate

Generating a revocation certificate will allow me to later revoke this keypair if it is compromised. It must be kept safe because it can render my keys useless ;-)

gpg --output ./[email protected] --gen-revoke [email protected]

Export the keypair/subkeys to a safe location and make the key safe to use

First export the private key:

gpg --export-secret-keys --armor [email protected] > [email protected]

Then export the public key:

gpg --export --armor [email protected] > [email protected]

Finally, you can export the sub-keys alone:

gpg --export-secret-subkeys [email protected] > /tmp/gpg/subkeys

We’ll see why afterwards.

Ideally, you should export your private key to a temporary in-memory file system. Alex proposed the following:

mkdir /tmp/gpg # create a temp folder
sudo mount -t tmpfs -o size=1M tmpfs /tmp/gpg

Once that’s mounted, you can safely write there and remove the folder once you’re done.

Once exported, back-up those keys in a safe location (e.g., Keepass).

Once you’re 100% it’s backed-up, delete the secret key from the gpg keyring:

gpg --delete-secret-key [email protected]

Now re-import the sub-keys. With this you’ll only have the sub-keys at your disposal (and you don’t need more than that on a daily basis):

gpg --import /tmp/gpg/subkeys

So simple steps:

  • create/mount the temporary in-memory file system
  • export your private key
  • back it up in a safe location
  • remove the temporary file system
  • bonus: burn the machine you’ve done this upon ;-)

To verify that you didn’t mess up, go ahead and try to add a new sub-key; you shouldn’t be able to:

gpg --edit-key [email protected]
gpg> addkey
Secret parts of primary key are not available.
gpg: Key generation failed: No secret key

That’s it!

How I can revoke a sub-key

Using Google! Err I mean like this:

First re-import my whole key (i.e., master + sub-keys)

gpg --allow-secret-key-import --import 

Second, edit the key and revoke the sub-key that I don’t want anymore:

gpg --edit-key [email protected]
gpg> list # list the keys
gpg> xyz # select the unwanted key
gpg> revkey # generate a revocation certificate
gpg> save

Once done, I can export/back-up the result and finally make sure to send the updated key to the key servers.

Where I’ve published my key

Once my key was ready, I’ve published it at various locations.

For starters I needed the full fingerprint (the 40 chars beauty):

gpg --fingerprint

In my case: 9AEC 7595 2F0F 8E52 65A8 4364 6448 ABB4 AEAD 81A2.

Just to be in the clear, if you need to share your key, always try to use the full fingerprint, certainly never the short version (8 hex chars one) nor the “long” (16 hex chars) since those are really unsafe.

First I sent the public key to the MIT key server using gpg:

gpg --send-keys [email protected]

Then I exported my public key to a file (ASCII-armored):

gpg --export --armor > dsebastien-pgp-key.asc

I then uploaded that file to my FTP, updated my about page to add the full fingerprint and a link to my public key. Then I added a blog post with the same information.

I’ve also sent an update on twitter the same. After that I’ve updated my Twitter bio to link to that tweet (optimizing character count :p).

Next up, I’ve uploaded the public key manually on Ubuntu’s key server.

Finally, I’ve updated my GitHub profile to add my PGP key.

Git client configuration

I’ve also updated my git client configuration in order to make my life easier.

  • git config –global user.signingkey 9AEC75952F0F8E5265A843646448ABB4AEAD81A2

This tells git which key to use. BTW, don’t enable automatic commit signing. Sign tags instead.

Verifying signatures is a breeze with git.


In a later post, I’ll explain how I use my PGP keys with SSH, git and my Yubikey.

That’s all folks!

So you want to be safe(r) while accessing your online bank account?

Saturday, May 14th, 2016

Web browsers

One quick tip: if you want to access sensitive Websites safely (e.g., your online bank, your taxes, …), then:

  • do so in a different Web browser than the one you generally use.
  • make sure that the browser you use for sensitive sites is NOT your default browser (i.e., the one that opens when you click on links in e-mails for example)
  • make sure that your browser is up to date
  • make sure that you never use that browser for anything else
  • do NOT visit anything else (i.e., no other tabs) at the same time
  • quickly check that you don’t have weird extensions or plugins installed (you could very well have been p0wned by any application installed on your machine)
  • make sure that you configure very strict security rules on that browser (e.g., disable caching, passwords/form data storage, etc)

Why does this help? Well if your machine isn’t part of a botnet or infected with hundreds of malwares yet, then the above could still protect you against commonly found vulnerabilities (e.g., cross-site request forgery), vulnerabilities exploited through a different tab in your browser, etc.

Personally I use Google Chrome as my default Web browser and Mozilla Firefox whenever I need to access sensitive sites.

Do NOT consider this as bulletproof though, it’s nothing but ONE additional thing you can do to protect yourself; you’re still exposed to many security risks, the Web is a dangerous place ;-)


Thursday, February 18th, 2016

I’ve received a YubiKey Neo today and thus I’m going to start experimenting with it. If you care about security but never heard about YubiKey or Universal 2nd Factor (U2F) then you should probably take a look at how awesome that stuff is :)

Here’s a list of things I’m planning on using it as second authentication factor for:

  • Google tools & Google Chrome
  • Windows authentication
  • OpenVPN
  • KeePass
  • Android

I’ll also look at other ways I could leverage U2F… If you’ve got tips & tricks to share, don’t hesitate to tell me!

Security HTTP Headers FTW

Saturday, December 19th, 2015

In the last couple of months, I’ve tried to improve the overall security of this site. I’ve started by putting my server behind Cloudflare to get HTTPS (along with other nice availability/performance improvements). Then I closed my eyes and enabled HSTS. I even dared adding this site to the HSTS preload list (i.e., the list of HSTS-enabled websites loaded in all modern browsers). Weakest-Link-Graphic Today I’m taking this a step further with the addition of some security-related HTTP headers. You might say that this was the very first thing I should’ve done and you’d be right to say so, but here comes :) From now on, if you take a look at the initial response, you’ll see that the following headers (among others) are being sent to you:

X-Frame-Options "SAMEORIGIN"
X-Xss-Protection "1; mode=block"
X-Content-Type-Options "nosniff"
content-security-policy: "default-src 'self'; style-src 'self' 'unsafe-inline'; img-src * data:; script-src 'self' 'unsafe-inline' https://*;child-src 'self' https://*; font-src 'self' data:; frame-ancestors 'none';report-uri; connect-src 'self'; form-action 'self'; upgrade-insecure-requests; reflected-xss block; base-uri; object-src 'none'"

The X-* headers give additional protection against clickjacking, cross-site scripting (XSS) and preventing some user agents from doing mime type sniffing. Those are nice, but the main one is the Content Security Policy (CSP). There are tons of articles about what a CSP is and how to configure one so I won’t go into the details of that. Any security expert will quickly notice that this isn’t the strictest CSP (far from it) because it allows ‘unsafe-inline’ for scripts & styles. The thing is that adding hashes or nonces to all scripts and styles is not an easy thing to do; even less so when you inherit that from many wordpress plugins… Also, some minified code (e.g., jQuery plugins) uses eval (evil?). For now, I’ve decided to lower my security goal. I’ll surely revisit this later though (probably with the new version of the site). Notice that the CSP makes some older HTTP headers redundant (e.g., X-Frame-Options) but I’m still keeping the older variants just for the sake of wider support. These will go away over time. Here are some tips if you want to go about and create a CSP for your site/domain:

  • start with the report-only mode. It’ll only log errors in the console and will not actually block anything; this is a great starting point:
    content-security-policy-report-only: default-src 'none';
  • use tools such as the CSP extension for Fiddler or an online CSP generator
  • once you’ve got rid of all console errors, remove ‘report-only’ to make your CSP effective
  • configure a ‘report-uri’ to be aware of CSP-related issues. Just be careful with this as attackers might probably take advantage of that (i.e., do not mail yourself all violations :p)

More generally, you can use online tools such as this one to review your site’s security headers. If you look at my site there, you’ll see that I could add HTTP Public Key Pinning (HPKP) headers to improve security a bit more. I won’t do it though as I don’t want my site to break whenever CloudFlare decides to present a new certificate in front of my site…

As a side note, if you’re using Apache, you can configure security headers through .htaccess files and the headers module (mod_headers). Here’s an example:

Header always set X-Frame-Options "SAMEORIGIN"

I’m sure that this site still has many vulnerabilities, but there aren’t enough hours in the day for me to fix everything at once. I have other improvements in mind, but that’ll be for later! :)

Use bash to decompile Java class files recursively

Tuesday, December 8th, 2015

Here’s a quick one. As you *might* know, I like Bash (even though I’m a Win* user..), so here’s an alias I’ve added recently:

export JAD_HOME=...
append_to_path $JAD_HOME
alias jad='(jad.exe)&'
jadr() { ("jad.exe" "-d" "." "-s" "java" "-r" "**/*.class")& }

With the above, jad will execute ‘jad’ and ‘jadr’ will recursively decompile all Java class files in the current/sub folders.

HSTS enabled!

Friday, June 19th, 2015

Hey everyone!

As noted in my previous post, I’ve finally switched my domain to HTTPS. I was reluctant to enable HSTS (HTTP Strict Transport Security) at first but after looking at this talk, I’ve decided to just go with the flow and enable it on CloudFlare:


Basically it means that, as of right now, you’ll always use HTTPS when visiting my website, even if you try and visit the old HTTP URL. This will occur not only because my Apache server is configured to automatically redirect you to the HTTPS version, but because your browser will automatically go to the HTTPS URL. Why will it do that? Because my site is now sending the HSTS HTTP header:

strict-transport-security:max-age=15552000; includeSubDomains; preload

Basically that header tells your browser: This is an HTTPS enabled website, always use HTTPS if you come back here. Please do this for this domain and all sub-domains for the next six months..

For now, as my site isn’t in the browsers HSTS preload list yet (I’ve just submitted it), you may visit this site once more using plain HTTP but as soon as your browser will see the HSTS HTTP header it’ll remember to always switch to HTTPS.

Why does HSTS matter? Because it will protect YOU against man-in-the-middle attacks.. not that this Website is sensitive in any way, but as a good Web citizen I have to do what I can, right? ;-)

I was hesitant to enable this because I’ve just signed up with CloudFlare and if they decide to drop their free subscription plan then it means that I’ll be forced to find either another similar solution or buy a certificate that I can install on my web host; in my case OVH doesn’t allow importing third party certificates and they charge about 50€ per year for that (which is wayyyyyyyy too much for a personal website).

The bet that I’m making by enabling HSTS now is simply that the free subscription model of CloudFlare will remain available for at least 2-3 years (hopefully much longer) and that in the meantime, given how Mozilla, Google major players and others are pushing for HTTPS everywhere, the overall accessibility/affordability of HTTPS for personal websites will have improved. If I’m wrong well then I’ll either pay if you show me enough love or shut this thing down ;-)