Coder Social home page Coder Social logo

pstadler / keybase-gpg-github Goto Github PK

View Code? Open in Web Editor NEW
2.6K 39.0 180.0 284 KB

Step-by-step guide on how to create a GPG key on keybase.io, adding it to a local GPG setup and using it with Git and GitHub.

gpg keybase signing cryptography guide howto

keybase-gpg-github's Introduction

Set up Keybase.io, GPG & Git to sign commits on GitHub

This is a step-by-step guide on how to create a GPG key on keybase.io, adding it to a local GPG setup and use it with Git and GitHub.

Although this guide was written for macOS, most commands should work in other operating systems as well.

There's a video published by Timothy Miller explaining some parts of this guide. Discussion on Hacker News.

Note: If you don't want to use Keybase.io, follow this guide instead. For manually transferring keys to different hosts, check out this answer on Stack Overflow.

Requirements

$ brew install gpg
$ brew install --cask keybase

You should already have an account with Keybase and be signed in locally using $ keybase login. In case you need to set up a new device first, follow the instructions provided by the keybase command during login.

Make sure your local version of Git is at least 2.0 ($ git --version) to automatically sign all your commits. If that's not the case, use Homebrew to install the latest Git version: $ brew install git.

Create a new GPG key on keybase.io

$ keybase pgp gen --multi
# Enter your real name, which will be publicly visible in your new key: Patrick Stadler
# Enter a public email address for your key: [email protected]
# Enter another email address (or <enter> when done):
# Push an encrypted copy of your new secret key to the Keybase.io server? [Y/n] Y
# ▶ INFO PGP User ID: Patrick Stadler <[email protected]> [primary]
# ▶ INFO Generating primary key (4096 bits)
# ▶ INFO Generating encryption subkey (4096 bits)
# ▶ INFO Generated new PGP key:
# ▶ INFO   user: Patrick Stadler <[email protected]>
# ▶ INFO   4096-bit RSA key, ID CB86A866E870EE00, created 2016-04-06
# ▶ INFO Exported new key to the local GPG keychain

Set up Git to sign all commits

$ gpg --list-secret-keys --keyid-format LONG
# /Users/pstadler/.gnupg/secring.gpg
# ----------------------------------
# sec   4096R/E870EE00 2016-04-06 [expires: 2032-04-02]
# uid                  Patrick Stadler <[email protected]>
# ssb   4096R/F9E3E72E 2016-04-06

$ git config --global user.signingkey E870EE00
$ git config --global commit.gpgsign true

Add public GPG key to GitHub

$ open https://github.com/settings/keys
# Click "New GPG key"

# We can then use `export` with the `-q` or query flag to match on our key (the first 16 characters should do..) 
$ keybase pgp export -q CB86A866E870EE00 | pbcopy # copy public key to clipboard
# Paste key, save

Import key to GPG on another host

$ keybase pgp export
# ▶ WARNING Found several matches:
# user: Patrick Stadler <[email protected]>
# 4096-bit RSA key, ID CB86A866E870EE00, created 2016-04-06

# user: keybase.io/ps <[email protected]>
# 4096-bit RSA key, ID 31DBBB1F6949DA68, created 2014-03-26

$ keybase pgp export -q CB86A866E870EE00 | gpg --import
$ keybase pgp export -q CB86A866E870EE00 --secret | gpg --allow-secret-key-import --import

After importing you probably want to locally trust your own key, otherwise you will see gpg: WARNING: This key is not certified with a trusted signature! when running git log --show-signature.

$ gpg --edit-key CB86A866E870EE00
gpg> trust

Please decide how far you trust this user to correctly verify other users' keys
(by looking at passports, checking fingerprints from different sources, etc.)

  1 = I don't know or won't say
  2 = I do NOT trust
  3 = I trust marginally
  4 = I trust fully
  5 = I trust ultimately
  m = back to the main menu

Your decision? 5
Do you really want to set this key to ultimate trust? (y/N) y

gpg> quit

Troubleshooting: gpg failed to sign the data

If you cannot sign a commit after running through the above steps, and have an error like:

$ git commit -m "My commit"
# error: gpg failed to sign the data
# fatal: failed to write commit object

You can run echo "test" | gpg --clearsign to find the underlying issue.

If the above succeeds without error, then there is likely a configuration problem that is preventing git from selecting or using the secret key. Confirm that your gitconfig user.email matches the secret key that you are using for signing.

Another solution is set up Git to use GPG program on Windows

$ git config --global user.signingkey E870EE00
$ git config --global commit.gpgsign true
$ git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"

Optional: Set as default GPG key

$ $EDITOR ~/.gnupg/gpg.conf
# Add line:
default-key E870EE00

Optional: Fix for Git UIs

If you use a UI such as Git Tower or Github Desktop, you may need to configure git to point to the specific gpg executable:

git config --global gpg.program $(which gpg)

Optional: Disable TTY

If you have problems with making autosigned commits from IDE or other software add no-tty config

$ $EDITOR ~/.gnupg/gpg.conf
# Add line:
no-tty

Optional: Setting up TTY

Depending on your personal setup, you might need to define the tty for gpg whenever your passphrase is prompted. Otherwise, you might encounter an Inappropriate ioctl for device error.

$ $EDITOR ~/.profile # or other file that is sourced every time
# Paste these lines
GPG_TTY=$(tty)
export GPG_TTY

Optional: In case you're prompted to enter the password every time

Some people found that this works out of the box w/o following these steps.

Method 1 - gpg-agent + pinentry-mac

Install pinentry-mac:

$ brew install pinentry-mac

Set up the agent:

$ $EDITOR ~/.gnupg/gpg-agent.conf
# Paste this line:
pinentry-program /usr/local/bin/pinentry-mac

Now git commit -S, it will ask your password and you can save it to macOS keychain.

pinentry

Method 2 - GPG Suite

Some people find that pinentry installed with brew does not allow the password to be saved to macOS's keychain.

If you do not see "Save in Keychain" after following Method 1, first uninstall the version of pinentry-mac installed with brew:

$ brew uninstall pinentry-mac

Now install the GPG Suite versions, available from gpgtools.org, or from brew by running:

$ brew install --cask gpg-suite

Once installed, open Spotlight and search for "GPG Suite", or open system preferences and select "GPG Suite"

Select the Default Key if it is not already selected, and ensure "Store in OS X Keychain" is checked:

gpg preferences

The gpg-agent.conf is different from Method 1:

Set up the agent:

$ $EDITOR ~/.gnupg/gpg-agent.conf
# GPG Suite should pre-populate with something similar to the following:
default-cache-ttl 600
max-cache-ttl 7200

Testing without a Git Commit

While a full end-to-end test by committing something to git will confirm for sure if things are working, a quick thing you can check is:

echo "test" | gpg --clearsign

This will output something like this if everything goes well:

$ echo "test" | gpg --clearsign
gpg: WARNING: server 'gpg-agent' is older than us (2.2.40 < 2.4.0)
gpg: Note: Outdated servers may lack important security fixes.
gpg: Note: Use the command "gpgconf --kill all" to restart them.
gpg: using "9DAC53FB18AB8C5DF0E2AA5B330CB62AE334C5E2" as default secret key for signing
gpg: problem with fast path key listing: IPC parameter error - ignored
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA256

test
-----BEGIN PGP SIGNATURE-----

iQEzBAEBCAAdFiEEmpcZZDDypeoq25Aer4d9fatgnzQFAmPmbXEACgkQr4d9fatg
nzQ/RAf9Elo6RUbb1xWdyPVHqS6Eq67eWmbJ62WriI+2ldMjj8lZp4XtcZ0KzXnO
0U4moVhZyQqBQ1syDC8UNXsTI7pzbRuZ1dzs5tjo+6UuqGfzpgurvw//3L/LxujJ
5asFq//sDNLCHFUAFDbmuWqfcMqpp/KqtaJr8EuCSb/3HSy4J8lMNGyQ4wmpQs5U
Qr5IPLq07NQrOQC3d4vXOmWqY9EZYeSbf0QWCMiErHLxm/jQY+TP88lNre99GmED
4mAD2+I5wd33MizbjfTSH/RAeT5MdLwiBzc6kVjxu4BWusPmdUgLs7vPuP3qeqMQ
q9VnL6mMsaFm0rKnID/MoOPtaghgSA==
=1T8z
-----END PGP SIGNATURE-----

keybase-gpg-github's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

keybase-gpg-github's Issues

Brew cask install gpg-suite

To have your key passphrase stored in the macOS Keychain, GitHub recommends using GPG Suite according to https://help.github.com/articles/signing-commits-using-gpg/

Like the rest of your instructions, this can be installed via brew with:
brew cask install gpg-suite

This may be a better first option/default than your existing Method 1 listed in https://github.com/pstadler/keybase-gpg-github#optional-in-case-youre-prompted-to-enter-the-password-every-time, and I don't think the subsequent steps (open Preferences, change config file) that you have for your existing Method 2 are necessary

gpg-agent --write-env-file obsolete

Not sure when this happened, but running gpg-agent as per readme:

$ gpg-agent --daemon --write-env-file ~/.gnupg/.gpg-agent-info
gpg-agent[1389]: WARNING: "--write-env-file" is an obsolete option - it has no effect
$ gpg-agent --version
gpg-agent (GnuPG/MacGPG2) 2.2.3
libgcrypt 1.8.1
Copyright (C) 2017 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Despite the fact that this is an obsolete option, the previously generated .gpg-agent-info file does work and does seem to be necessary.

i.e.

$ git commit --allow-empty -m "empty commit"

You need a passphrase to unlock the secret key for
user: "Lucy Davies <[email protected]>"
2048-bit RSA key, ID AB609F34, created 2016-10-20 (main key ID E334C5E2)

Enter passphrase:

vs

$ source ~/.gnupg/.gpg-agent-info
$ export GPG_AGENT_INFO
$ echo $GPG_AGENT_INFO
/Users/lucy/.gnupg/S.gpg-agent:1489:1
$ git commit --allow-empty -m "empty commit"

You need a passphrase to unlock the secret key for
user: "Lucy Davies <[email protected]>"
2048-bit RSA key, ID AB609F34, created 2016-10-20 (main key ID E334C5E2)

[master f357c8d] empty commit

Also, the use-standard-socket option is obsolete:

gpg-agent[8927]: /Users/lucy/.gnupg/gpg-agent.conf:1: obsolete option "use-standard-socket" - it has no effect

For now, until I can figure out how to use this newer version of gpg-agent, I've just got this in my bashrc:

# GPG agent
if test -f ~/.gnupg/.gpg-agent-info -a -n "$(pgrep gpg-agent)"; then
    # TODO: where does this 1489:1 come from?
    export GPG_AGENT_INFO=~/.gnupg/S.gpg-agent:1489:1
    GPG_TTY=$(tty)
    export GPG_TTY
else
    echo "Starting gpg-agent daemon"
    eval $(gpg-agent --daemon)
fi

Error: gpg failed to sign the data

Hi,

I've followed the exact steps, but when I try to commit I get the following message:

error: gpg failed to sign the data
fatal: failed to write commit object

I made sure git us using the right PGP program, name and email. All matching the info in my GPG key.

Not quite sure what's going on, any suggestions?

Save password to keychain

Hello everybody,
Thanks for the instructions but the Pinentry-Mac program doesn't save the password even when I tick the box. You describe to do something with gpg-agent-info but I don't have that file.
Is there something new (something changed) since the writing of the article?

Thanks in advance!
gpg (GnuPG) 2.2.11

Add fix for windows git bash in documentation

As git bash uses it's default gpg program which is located by default at C:\Program Files\Git\usr\bin\gpg.exe and keybase uses the gpg program of windows which is installed by default at C:\Program Files (x86)\GnuPG\bin\gpg.exe so it's obvious to get the following error while performing commit in git bash -:

gpg: skipped "3E81C*******": secret key not available
gpg: signing failed: secret key not available
error: gpg failed to sign the data
fatal: failed to write commit object

So it would be very helpful if you add this fix (to run the following command in git bash) in the documentation for the above error

git config --global gpg.program "C:\Program Files (x86)\GnuPG\bin\gpg.exe"

PS-: there is one fix like this for Git UIs but that takes the git bash default gpg program in windows

Instructions for pinentry-mac seem to be unnecessary on Sierra

I'm on Sierra and had previously installed gpg using Homebrew, but I hadn't done anything further to configure gpg-agent. My .gnupg/gpg-agent.conf had the following in it:

pinentry-program /Library/Frameworks/Libmacgpg.framework/Versions/A/Resources/pinentry-mac.app/Contents/MacOS/pinentry-mac

This seems to work correctly without any further steps, in other words, I'm able to use git commit -S without being prompted for the key password.

Can anyone confirm that Sierra makes this section unnecessary?

no `use-agent` line in my gpg.conf

When I came to the part where you said "uncomment the use-agent line" under Enable Use Agent I couldn't find it. Here's my conf.

# Options for GnuPG
# Copyright 1998, 1999, 2000, 2001, 2002, 2003,
#           2010 Free Software Foundation, Inc.
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This file is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Unless you specify which option file to use (with the command line
# option "--options filename"), GnuPG uses the file ~/.gnupg/gpg.conf
# by default.
#
# An options file can contain any long options which are available in
# GnuPG. If the first non white space character of a line is a '#',
# this line is ignored.  Empty lines are also ignored.
#
# See the man page for a list of options.

# Uncomment the following option to get rid of the copyright notice

#no-greeting

# If you have more than 1 secret key in your keyring, you may want to
# uncomment the following option and set your preferred keyid.

default-key 607DC363

# If you do not pass a recipient to gpg, it will ask for one.  Using
# this option you can encrypt to a default key.  Key validation will
# not be done in this case.  The second form uses the default key as
# default recipient.

#default-recipient some-user-id
#default-recipient-self

# By default GnuPG creates version 4 signatures for data files as
# specified by OpenPGP.  Some earlier (PGP 6, PGP 7) versions of PGP
# require the older version 3 signatures.  Setting this option forces
# GnuPG to create version 3 signatures.

#force-v3-sigs

# Because some mailers change lines starting with "From " to ">From "
# it is good to handle such lines in a special way when creating
# cleartext signatures; all other PGP versions do it this way too.
# To enable full OpenPGP compliance you may want to use this option.

#no-escape-from-lines

# When verifying a signature made from a subkey, ensure that the cross
# certification "back signature" on the subkey is present and valid.
# This protects against a subtle attack against subkeys that can sign.
# Defaults to --no-require-cross-certification.  However for new
# installations it should be enabled.

require-cross-certification


# If you do not use the Latin-1 (ISO-8859-1) charset, you should tell
# GnuPG which is the native character set.  Please check the man page
# for supported character sets.  This character set is only used for
# metadata and not for the actual message which does not undergo any
# translation.  Note that future version of GnuPG will change to UTF-8
# as default character set.

#charset utf-8

# Group names may be defined like this:
#   group mynames = paige 0x12345678 joe patti
#
# Any time "mynames" is a recipient (-r or --recipient), it will be
# expanded to the names "paige", "joe", and "patti", and the key ID
# "0x12345678".  Note there is only one level of expansion - you
# cannot make an group that points to another group.  Note also that
# if there are spaces in the recipient name, this will appear as two
# recipients.  In these cases it is better to use the key ID.

#group mynames = paige 0x12345678 joe patti

# Some old Windows platforms require 8.3 filenames.  If your system
# can handle long filenames, uncomment this.

#no-mangle-dos-filenames

# Lock the file only once for the lifetime of a process.  If you do
# not define this, the lock will be obtained and released every time
# it is needed - normally this is not needed.

#lock-once

# GnuPG can send and receive keys to and from a keyserver.  These
# servers can be HKP, email, or LDAP (if GnuPG is built with LDAP
# support).
#
# Example HKP keyservers:
#      hkp://keys.gnupg.net
#
# Example LDAP keyservers:
#      ldap://pgp.surfnet.nl:11370
#
# Regular URL syntax applies, and you can set an alternate port
# through the usual method:
#      hkp://keyserver.example.net:22742
#
# If you have problems connecting to a HKP server through a buggy http
# proxy, you can use keyserver option broken-http-proxy (see below),
# but first you should make sure that you have read the man page
# regarding proxies (keyserver option honor-http-proxy)
#
# Most users just set the name and type of their preferred keyserver.
# Note that most servers (with the notable exception of
# ldap://keyserver.pgp.com) synchronize changes with each other.  Note
# also that a single server name may actually point to multiple
# servers via DNS round-robin.  hkp://keys.gnupg.net is an example of
# such a "server", which spreads the load over a number of physical
# servers.  To see the IP address of the server actually used, you may use
# the "--keyserver-options debug".

keyserver hkp://keys.gnupg.net
#keyserver http://http-keys.gnupg.net
#keyserver mailto:[email protected]

# Common options for keyserver functions:
#
# include-disabled = when searching, include keys marked as "disabled"
#                    on the keyserver (not all keyservers support this).
#
# no-include-revoked = when searching, do not include keys marked as
#                      "revoked" on the keyserver.
#
# verbose = show more information as the keys are fetched.
#           Can be used more than once to increase the amount
#           of information shown.
#
# use-temp-files = use temporary files instead of a pipe to talk to the
#                  keyserver.  Some platforms (Win32 for one) always
#                  have this on.
#
# keep-temp-files = do not delete temporary files after using them
#                   (really only useful for debugging)
#
# honor-http-proxy = if the keyserver uses HTTP, honor the http_proxy
#                    environment variable
#
# broken-http-proxy = try to work around a buggy HTTP proxy
#
# auto-key-retrieve = automatically fetch keys as needed from the keyserver
#                     when verifying signatures or when importing keys that
#                     have been revoked by a revocation key that is not
#                     present on the keyring.
#
# no-include-attributes = do not include attribute IDs (aka "photo IDs")
#                         when sending keys to the keyserver.

#keyserver-options auto-key-retrieve

# Uncomment this line to display photo user IDs in key listings and
# when a signature from a key with a photo is verified.

#show-photos

# Use this program to display photo user IDs
#
# %i is expanded to a temporary file that contains the photo.
# %I is the same as %i, but the file isn't deleted afterwards by GnuPG.
# %k is expanded to the key ID of the key.
# %K is expanded to the long OpenPGP key ID of the key.
# %t is expanded to the extension of the image (e.g. "jpg").
# %T is expanded to the MIME type of the image (e.g. "image/jpeg").
# %f is expanded to the fingerprint of the key.
# %% is %, of course.
#
# If %i or %I are not present, then the photo is supplied to the
# viewer on standard input.  If your platform supports it, standard
# input is the best way to do this as it avoids the time and effort in
# generating and then cleaning up a secure temp file.
#
# The default program is "xloadimage -fork -quiet -title 'KeyID 0x%k' stdin"
# On Mac OS X and Windows, the default is to use your regular JPEG image
# viewer.
#
# Some other viewers:
# photo-viewer "qiv %i"
# photo-viewer "ee %i"
# photo-viewer "display -title 'KeyID 0x%k'"
#
# This one saves a copy of the photo ID in your home directory:
# photo-viewer "cat > ~/photoid-for-key-%k.%t"
#
# Use your MIME handler to view photos:
# photo-viewer "metamail -q -d -b -c %T -s 'KeyID 0x%k' -f GnuPG"

Examples should be with placeholders

Sometimes people just copy/paste examples/documentation.
Maybe is better to put a note or a placeholder.

Example:

$ git config --global user.signingkey [KEY-ID-HERE]
$ git config --global commit.gpgsign true

Passphrase timeout

It seems the passphrase is only kept for a few seconds. Is there a way to increase this? I've tried a bunch of stuff like default-ttl etc. but none of those seem to have worked for me.

Doesn't seem to play ball with GitHub Desktop & PyCharm

I followed the steps and seemed to get everything to work apart from GitHub Desktop client and PyCharm (I assume fixing GitHub Desktop will fix PyCharm as they both show the same error: "gpg failed to sign the data fatal: failed to write commit object".

Committing using the CLI doesn't prompt me for a password each time either.

Anyone have any ideas on fixing/debugging this?

Use the first 16 characters or ID when exporting key to clipboard?

In:

# We can then use `export` with the `-q` or query flag to match on our key (the first 16 characters should do..) 
$ keybase pgp export -q CB86A866E870EE00 | pbcopy # copy public key to clipboard

Should it be the first 16 characters or the ID? Even though the ID is 16 characters the wording was confusing for me and maybe for others?

In case of "command get_passphrase failed: Inappropriate ioctl for device"

For some reason I had to setup the GPG TTY variable on my bash when I tried to sign my commit (i.e. -S flag) because of passphrase, which is new to me since I usually have the passphrase prompt within my terminal, so who knows, might be a new GPG version.

Anyway, fixed it with:

GPG_TTY=$(tty)
export GPG_TTY

Might be worth adding it to the README.md under common issues and/or what not.

Need Help

Hi, please I need your help.

I am just entering into the world of secrets and github.

I created gpg keys (public and private). I added the public key to my github account.
I used the git secret to secure a file before pushing to github.

Now in my AWS using SSH, I cloned the project. I decided to use git secret reveal and I was presented with this error

git-secret: abort: no public keys for users found. run 'git secret tell email@address'.

Please can you guide me on what to do to be able reveal the file?

I feel I need to import the public key in github but I don't know how.

Thanks

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.