diff --git a/README.md b/README.md
index 7d7c063..241ec56 100644
--- a/README.md
+++ b/README.md
@@ -32,7 +32,8 @@ The default time-based authentication codes are derived from a hash of the
 key and the current time, so it is important that the system clock have at
 least one-minute accuracy.
 
-The keychain is stored unencrypted in the text file `$HOME/.2fa`.
+The keychain is stored unencrypted in the text file $HOME/.2fa
+or in $XDG_CONFIG_HOME/2fa if XDG_CONFIG_HOME is set.
 
 ## Example
 
diff --git a/main.go b/main.go
index a8d173c..b33a315 100644
--- a/main.go
+++ b/main.go
@@ -33,7 +33,8 @@
 // the key and the current time, so it is important that the system clock have
 // at least one-minute accuracy.
 //
-// The keychain is stored unencrypted in the text file $HOME/.2fa.
+// The keychain is stored unencrypted in the text file $HOME/.2fa
+// or in $XDG_CONFIG_HOME/2fa if XDG_CONFIG_HOME is set.
 //
 // Example
 //
@@ -107,6 +108,9 @@ func main() {
 	flag.Parse()
 
 	k := readKeychain(filepath.Join(os.Getenv("HOME"), ".2fa"))
+	if os.Getenv("XDG_CONFIG_HOME") != "" {
+		k = readKeychain(filepath.Join(os.Getenv("XDG_CONFIG_HOME"), "2fa"))
+	}
 
 	if *flagList {
 		if flag.NArg() != 0 {