Encrypted overlay filesystem written in Go
An encrypted overlay filesystem written in Go. Official website: https://nuetzlich.net/gocryptfs (markdown source).

gocryptfs is built on top the excellent go-fuse FUSE library. This project was inspired by EncFS and strives to fix its security issues while providing good performance (benchmarks). For details on the security of gocryptfs see the Security design document.
All tags from v0.4 onward are signed by the gocryptfs signing key. Please check Signed Releases for details.
Current Status
gocryptfs has reached version 1.0 on July 17, 2016. It has gone through hours and hours of stress (fsstress, extractloop.bash) and correctness testing (xfstests). It is now considered ready for general consumption.
The old principle still applies: Important data should have a backup. Also, keep a copy of your master key (printed at init) in a safe place. This allows you to access the data even if the gocryptfs.conf config file is damaged or you lose the password.
The security of gocryptfs has been audited in March 3, 2017. The audit is available here (defuse.ca).
Platforms
Linux is gocryptfs' native platform.
Beta-quality macOS support is available, which means most things work fine but you may hit an occasional problem. Check out ticket #15 for the history of macOS support but please create a new ticket if you hit a problem.
For Windows, an independent C++ reimplementation can be found here: cppcryptfs
Standalone tools:
gocryptfs-inspect is Python tool that can decrypt files & file names without using FUSE.
gocryptfs-create-folder is a Python tool can encrypt a directory without using FUSE.
Installation
Precompiled binaries that work on all x86_64 Linux systems are available for download from the github releases page. The
fuse package from your distribution must be installed for mounting to work.
gocryptfs is also available as a package in most distributions. Examples:
- Debian, Ubuntu:
apt install gocryptfs - Arch:
pacman -S gocryptfs - MacPorts:
port install gocryptfs
Testing
gocryptfs comes with is own test suite that is constantly expanded as features are added. Run it using ./test.bash. It takes about 1 minute and requires FUSE as it mounts several test filesystems.
The stress_tests directory contains stress tests that run indefinitely.
In addition, I have ported xfstests to FUSE, the result is the fuse-xfstests project. gocryptfs passes the "generic" tests with one exception, results: XFSTESTS.md
A lot of work has gone into this. The testing has found bugs in gocryptfs as well as in the go-fuse library.
Compile
Install Go 1.13 or higher:
- Debian/Ubuntu:
apt install golang - Fedora:
dnf install golang
$ git clone https://github.com/rfjakob/gocryptfs.git $ cd gocryptfs $ ./build-without-openssl.bash
This will compile a static binary that uses the Go stdlib crypto backend.
If you want to use the OpenSSL crypto backend (faster on old CPUs lacking AES-NI), you have to install a few dependencies:
- Debian/Ubuntu:
apt install libssl-dev gcc pkg-config - Fedora:
dnf install openssl-devel gcc pkg-config
$ ./build.bash
Use
$ mkdir cipher plain $ ./gocryptfs -init cipher $ ./gocryptfs cipher plain
See the Quickstart page for more info.
The MANPAGE.md describes all available command-line options.
Use: Reverse Mode
$ mkdir cipher plain $ ./gocryptfs -reverse -init plain $ ./gocryptfs -reverse plain cipher
Graphical Interface
The SiriKali project supports gocryptfs and runs on Linux and OSX.
cppcryptfs on Windows provides its own GUI.
Stable CLI ABI
If you want to call gocryptfs from your app or script, see CLI_ABI.md for the official stable ABI. This ABI is regression-tested by the test suite.
Storage Overhead
- Empty files take 0 bytes on disk
- 18 byte file header for non-empty files (2 bytes version, 16 bytes random file id)
- 32 bytes of storage overhead per 4kB block (16 byte nonce, 16 bytes auth tag)
Performance
Since version 0.7.2, gocryptfs is as fast as EncFS in the default mode, and significantly faster than EncFS' "paranoia" mode that provides a security level comparable to gocryptfs.
On CPUs without AES-NI, gocryptfs uses OpenSSL through a thin wrapper called stupidgcm. This provides a 4x speedup compared to Go's builtin AES-GCM implementation. See CPU-Benchmarks for details, or run gocryptfs -speed to see the encryption performance of your CPU. Example for a CPU with AES-NI:
$ ./gocryptfs -speed
gocryptfs v2.2.0-beta1-5-g52b0444-dirty; go-fuse v2.1.1-0.20210825171523-3ab5d95a30ae; 2021-09-14 go1.17.1 linux/amd64
cpu: Intel(R) Core(TM) i5-3470 CPU @ 3.20GHz; with AES acceleration
AES-GCM-256-OpenSSL 862.79 MB/s
AES-GCM-256-Go 997.71 MB/s (selected in auto mode)
AES-SIV-512-Go 159.58 MB/s
XChaCha20-Poly1305-OpenSSL 729.65 MB/s
XChaCha20-Poly1305-Go 843.97 MB/s (selected in auto mode)
You can run ./benchmark.bash to run gocryptfs' canonical set of benchmarks that include streaming write, extracting a linux kernel tarball, recursively listing and finally deleting it. The output will look like this:
$ ./benchmark.bash
Testing gocryptfs at /tmp/benchmark.bash.xFD: gocryptfs v2.0; go-fuse v2.1.1-0.20210508151621-62c5aa1919a7; 2021-06-06 go1.16.5 linux/amd64
WRITE: 262144000 bytes (262 MB, 250 MiB) copied, 0,698174 s, 375 MB/s
READ: 262144000 bytes (262 MB, 250 MiB) copied, 0,268916 s, 975 MB/s
UNTAR: 8,970
MD5: 4,846
LS: 1,851
RM: 2,367
Changelog
v2.6.1, 2025-08-10
- Fix warnings
cipherSize X: incomplete last block (Y bytes), padding to Z bytes
- MacOS: Fix GUI apps reporting failure to save files #914
- MacOS: Fix
test-without-openssl.bashtrying to build tests with openssl enabled
v2.6.0, 2025-07-14
- Upgrade to go-fuse v2.8.0
- Switch to the new go-fuse directory API( https://github.com/rfjakob/gocryptfs/commit/ae3c859c1179498a4882b4bd69c2243aa6912332 )
- Fix
-force_ownernot allowing file/dir create ( https://github.com/rfjakob/gocryptfs/issues/783 ) - Skip
TestBtrfsQuirksif mkfs.btrfs is not installed ( https://github.com/rfjakob/gocryptfs/issues/930 )
v2.5.4, 2025-04-13
- Drop
GOAMD64=v2frombuild.bash, there's user(s) still runningGOAMD64=v1CPUs
v2.5.3, 2025-04-05
- Fix
go installfailing withg: malformed file path "tests/fsck/malleablebase64/27AG8t-XZH7G9ou2OSDz\ng": invalid char '\n'
- Fix panic when go-fuse is newer than specified in go.mod (#897)
v2.5.2, 2025-03-19
- Use our own
syscallcompat.Setreuid(and friends) wrappers
- Upgrade
golang.org/x/sysagain - Provide arm64 binaries in releases in addition to amd64
v2.5.1, 2025-01-23
*Downgradegolang.org/x/sys to unbreak unix.Setreuid and -allow_other
(6d342f3,
#893, #892)**
v2.5.0, 2025-01-18
*Important fixes for-reverse mode affecting the virtual gocryptfs.diriv and
gocryptfs.longname..name files. The bug can cause file names* to become
undecryptable. To make sure that sync tools like rsync copy new, good copies,
gocryptfs v2.5.0 and later advance ctime and mtime for these files by 10 seconds.
* Fix -reverse mode sometimes (triggered by inode number reuse) returning stale
data for gocryptfs.diriv (#802)
Fix -reverse mode hardlinking gocryptfs.longname..name files of hardlinked
files together (#802)
- Fix
-reversemode ignoring-force-owner(#809) - Add workaround for excessive file fragementation on btrfs (#811)
-ctlsock: automatically delete orphaned colliding socket file (#776)- MacOS: Fix XTIMES panic on startup (#823)
- MacOS: merge kernel options before passing them on (#854, #557)
- Add
-fido2-assert-option(#807) -initnow accepts-masterkey
-passwd now ignores -extpass and -passfile for the new* password (#287, #882)
v2.4.0, 2023-06-10
- Try the
mount(2)syscall before falling back tofusermount(1). This means we
fusermount(1) at all if running as root or in a root-like namespace
(#697)
- Fix
-extpassmis-parsing commas (#730) - Fix
rm -Rmis-reportingwrite-protected directoryon gocryptfs on sshfs
v2.3.2, 2023-04-29
- Fix incorrect file size reported after hard link creation
v2.3.1, 2023-03-04
- Optimize NFS streaming write performance (#712,
- Use
debug.ReadBuildInfo()to provide some
build.bash (#701) .
- Fix bug that caused the
loggerprocess to be killed when started fromxfce4-terminal,
- MacOS: Fix reverse mount failing with
read-only file system(#690) - Make gocryptfs compile on riscv64 by switching from jacobsa/crypto
v2.3.0, 2022-10-21
- Identical to v2.3, just tagged once more in full semver x.y.z format. This make Go's fetching logic happy,
v2.3, 2022-08-28
- Add
-longnamemaxflag to-init(#499).
- Support for
NOCOLORenv variable (#617) - Fix
-forceownernot not affecting socket files (#629 - MacOS: fix inaccessible
gocryptfs.confin reverse mode (commit) - Raise ctlsock operation timeout from 1 to 10 seconds (#683)
v2.2.1, 2021-10-20
- Fix
-forceowneronly taking effect after 2 seconds (#609).
- MacOS: Fix build.bash failure with error
date: illegal option -- -whenSOURCEDATEEPOCHis set
-init: suggest xchacha on CPUs without AES acceleration (commit)-info: add contentEncryption to output
v2.2.0, 2021-09-25
-deterministic-names: new option for-init, both for reverse and forward mode.
gocryptfs.diriv files
(#151, #402, #592)
* New feature flag! You need gocryptfs v2.2 or higher to mount a filesystem that uses this flag.
-xchacha: new option for-init(forward mode only). Selects XChaCha20-Poly1305 for content encryption.
gocryptfs -speed what is fastest for your CPU, or read here
- Rewrite OpenSSL backend
-serialize_reads: get rid of delay logic by taking advantage of the kernel flag
FUSECAPASYNC_READ
(go-fuse commit,
gocryptfs commit)
- Make obsolete
-devrandomflag a no-op (commit) - Make
-forcedecodeflag a no-op (commit) - Fix reverse mode sometimes remapping most inode numbers to >281474976710656 (commit)
- This version will be called v2.2.0 (instead of v2.2) to comply with
v2.1, 2021-08-18
-fido2: do not request PIN ongocryptfs -initfixingFIDOERRUNSUPPORTED_OPTIONwith YubiKey
-sharedstorage: present stable inode numbers, fixing getcwd failures
-badname: make it possible to access content of invalid file names (#568).
- Implement recursive
gocryptfs.dirivcaching to fix exponential runtime with deep directories
- Implements fsync on directories (#587)
-reverse: implement-one-file-system(#475)-reverse: allow exclude-all-but (#588)
gocryptfs -reverse -exclude-wildcard '' -exclude-wildcard '!/my-important-files' /home/user /mnt/user.encrypted
- macOS: Fix
panic: using reserved ID 1on ExFAT (#585) - Switch to
pflagcli parsing library to support flags and arguments in any order
- Drop support for Go 1.11 & Go 1.12 (commit)
v2.0.1, 2021-06-07
- Fix symlink creation reporting the wrong size, causing git to report it as modified
v2.0, 2021-06-05
- Fix a few issues discovered by xfstests
v2.0-beta4, 2021-05-15
Make ACLs actually* work (pass-acl to enable) (#536)
- Blocklist
RENAMEEXCHANGEandRENAMEWHITEOUT(broken as discovered by fuse-xfstest/gocryptfs-2019-12)
v2.0-beta3, 2021-04-24
- MANPAGE: Split options into sections acc. to where they apply (#517)
-idle: count cwd inside the mount as busy (#533)- Make
gocryptfs.dirivandgocryptfs.xxx.namefiles world-readable to make encrypted backups easier
gocryptfs -fsck but otherwise ignored
* This fixes inheritance, but does not yet enforce them correctly
- Include
gocryptfs-xrayin binary releases (#496)
-sharedstorage and also without.
(commit 1,
commit 2,
#549)
- Add directory fd caching for 2x - 3x speed boost in small file ops compared to v2.0-beta2
v2.0-beta2, 2020-11-14
- Improve performance
- Fix GETATTR panic in reverse mode
v2.0-beta1, 2020-10-15
- Switch to the improved go-fuse v2 API
- Add support for FIDO2 tokens (
-fido2, #505) - Add
-encrypt-paths/-decrypt-pathsfunctionality togocryptfs-xray
- Accept multiple
-passfiles
- Make
-masterkey=stdinwork together with-passwd
- Fix
Unknown opcode 2016crash on Google Cloud
v1.8.0, 2020-05-09
- Enable ACL support (#453)
- Ignore
.nfsXXXtemporary files
- Handle inode number collisions from multiple devices
- Drop
-nonemptyfor fusermount3
- Reverse mode: improve inode number mapping and max=1000000000000000000 limitation
- Enable
--buildmode=pie(#460) - Migrate from dep to Go Modules
- go mod: update dependencies
gocryptfs -speed: add XChaCha20-Poly1305-Go
- Respect
GOMAXPROCSenvironment variable
- Completely remove Trezor-related code (commit 1364b44ae356da31e24e5605fe73a307e9d6fb03)
v1.7.1, 2019-10-06
- Support wild cards in reverse mode via
--exclude-wildcard
- Create
gocryptfs.dirivfiles with 0440 permissions to make it easier to
chmod gocryptfs.conf 0440 to allow mounting.
- Allow the
nofailoption in/etc/fstab -passwdcan now change the-scryptnparameter for existing filesystems
- Fix
-idleunmounting the filesystem despite recent activity
- tests: use /var/tmp instead of /tmp by default
v1.7, 2019-03-17
- Fix possible symlink race attacks in forward mode when using allow_other + plaintextnames
-allow_other and* -plaintextnames, you should upgrade.
Malicious users could trick gocryptfs into modifying files outside of CIPHERDIR,
or reading files inside CIPHERDIR that they should not have access to.
* If you do not use -plaintextnames (disabled per default), these attacks do
not work as symlinks are encrypted.
Forward mode has been reworked to use the "\at" family of system calls everywhere
(Openat/Unlinkat/Symlinkat/...).
* As a result, gocryptfs may run slightly slower, as the caching logic has been
replaced and is very simple at the moment.
* The possibility for such attacks was found during an internal code review.
- Reverse mode: fix excluded, unaccessible files showing up in directory listings
- gocryptfs-xray: add
-aessivflag for correctly parsing AES-SIV format files
- Ensure that standard fds 0,1,2 are always initialized
-extpassnow can be specified multiple times to support arguments containing spaces
- Drop Fstatat, Mkdirat, Syslinkat, Fchownat, Unlinkat, Renameat, Openat emulation of MacOS
- Use
Setreuidto robustly set the owner with allow_other (@slackner,
- Pack the rendered man page into the source code archive for user convenience
- Disable Trezor support again (commit 16fac26c57ba303bf60266d24c17f5243e5ea376)
v1.6.1, 2018-12-12
- Fix "Operation not supported" chmod errors on Go 1.11
v1.6, 2018-08-18
- Add
-e/-excludeoption for reverse mode
- Add support for the Trezor One HSM PR#247, thanks @xaionaro!
./build.bash -tags enable_trezor to compile with Trezor support
* Then, use gocryptfs -init -trezor to create a filesystem locked with a physical Trezor device.
* Note 2021-01-31: Support was removed again in gocryptfs v1.7. Please use -fido2 in gocryptfs v2.0.
- Only print master key once, on init
- Fall back to buffered IO even when passed
O_DIRECT
v1.5, 2018-06-12
- Support extended attributes (xattr) in forward mode
- Add
-fsckfunction
- Fix clobbered timestamps on MacOS High Sierra
- Add
-masterkey=stdinfunctionality
- Accept
-dev/-nodev,suid/nosuid,-exec/-noexec,
-ro/-rw flags to make mounting via /etc/fstab possible.
Thanks @mahkoh! (#233,
commit,
commit)
- Fix a
loggerpath issue on SuSE
- Stop printing the help text on a "flag provided but not defined"
v1.4.4, 2018-03-18
- Overwrite secrets in memory with zeros as soon as possible
- Fix Getdents problems on i386 and mips64le
- Make building with gccgo work
- MacOS: fix
osxfuse: vnode changed generation/Error code -36issue in go-fuse
- Fix various test issues on MacOS
v1.4.3, 2018-01-21
- Fix several symlink race attacks in connection with reverse mode
-allow_other
(issue #177)
- Fix problems with special names when using
-plaintextnames
- Add
-devrandomcommand-line option
- Add
-sharedstoragecommand-line option
- MacOS: let OSXFuse create the mountpoint if it does not exist
v1.4.2, 2017-11-01
- Add
Gopkg.tomlfile fordepvendoring and reproducible builds
- MacOS: deal with
.DS_Storefiles inside CIPHERDIR
- Reverse mode: fix ENOENT error affecting names exactly 176 bytes long
- Support kernels compiled with > 128 kiB FUSE request size (Synology NAS)
- Fix a startup hang when
$PATHcontains the mountpoint
v1.4.1, 2017-08-21
- Use memory pools for buffer handling (
- Implement and use the getdents(2) syscall for a more efficient
- Purge masterkey from memory as soon as possible
- Reverse mode: fix inode number collision between .name and .diriv
- Prevent the logger from holding stdout open
- MacOS: make testing without openssl work properly
- MacOS: specify a volume name
- Enable writing to write-only files
v1.4, 2017-06-20
- Switch to static binary releases
- Add
-force_owneroption to allow files to be presented as owned by a
- Add more specific exit codes for the most common failure modes,
- Reverse mode: make sure hard-linked files always return the same
- Display a shorter, friendlier help text by default.
- Parallelize file content encryption by splitting data blocks into two
- Prefetch random nonces in the background
- Add
-infooption to pretty-print infos about a filesystem.
v1.3, 2017-04-29
- Use HKDF to derive separate keys for GCM and EME
HKDF (enabled by default)
* This is a forwards-compatible change. gocryptfs v1.3 can mount
filesystems created by earlier versions but not the other way round.
- Enable Raw64 filename encoding by default (gets rid of trailing
==characters)
- Drop Go 1.4 compatibility. You now need Go 1.5 (released 2015-08-19)
- Add
-serialize_readscommand-line option
- Reject file-header-only files
- Increase max password size to 2048 bytes (#93)
- Use stable 64-bit inode numbers in reverse mode
- Passing "--" now also blocks "-o" parsing
v1.2.1, 2017-02-26
- Add an integrated speed test,
gocryptfs -speed - Limit password size to 1000 bytes and reject trailing garbage after the newline
- Make the test suite work on Mac OS X
- Handle additional corner cases in
-ctlsockpath sanitization - Use dedicated exit code 12 on "password incorrect"
v1.2, 2016-12-04
- Add a control socket interface. Allows to encrypt and decrypt filenames.
-ctlsock
- Under certain circumstances, concurrent truncate and read could return
- Coalesce 4kB ciphertext block writes up to the size requested through
- Add
-noprealloccommand-line option
- Preserve owner for symlinks an device files (fixes bug #64)
- Include rendered man page
gocryptfs.1in the release tarball
v1.1.1, 2016-10-30
- Fix a panic on setting file timestamps (go-fuse#131)
- Work around an issue in tmpfs that caused a panic in xfstests generic/075
- Optimize NFS streaming writes
v1.1, 2016-10-19
- Add reverse mode (#19)
AESSIV.
* New command-line options: -reverse, -aessiv
* Filesystems using reverse mode can only be mounted with gocryptfs v1.1
and later.
* The default, forward mode, stays fully compatible with older versions.
Forward mode will keep using GCM because it is much faster.
- Accept
-o foo,bar,baz-style options that are passed at the end of
- To prevent confusion, the old
-ooption had to be renamed. It is now
-ko. Arguments to -ko are passed directly to the kernel.
- New
-passfilecommand-line option. Provides an easier way to read
-extpass "/bin/cat FILE".
- Enable changing the password when you only know the master key
v1.0, 2016-07-17
- Deprecate very old filesystems, stage 3/3
-gcmiv128, -emenames, -diriv. These
are now always enabled.
- Add fallocate(2) support
- New command-line option
-o
- Add support for device files and suid binaries
- Experimental Mac OS X support. See
v0.12, 2016-06-19
- Deprecate very old filesystems, stage 2/3
- New command line option:
-ro
- Accept password from stdin as well (ticket #30)
v0.11, 2016-06-10
- Deprecate very old filesystems, stage 1/3
- Add rsync stress test "pingpong-rsync.bash"
- Build release binaries with Go 1.6.2
v0.10, 2016-05-30
- Replace
spacemonkeygo/opensslwithstupidgcm
stupidgcm.
* This should fix the compile issues
people are seeing with spacemonkeygo/openssl. It also gets us
a 20% performance boost for streaming writes.
- Automatically choose between OpenSSL and Go crypto issue #23
-openssl=auto is the new default
* Passing -openssl=true/false overrides the autodetection.
- Warn but continue anyway if fallocate(2) is not supported by the
- Fix statfs, by @lxp
- Fix a fsstress failure
v0.9, 2016-04-10
- Long file name support
- Refactor gocryptfs into multiple "internal" packages
- New command-line options:
-longnames: Enable long file name support (default true)
* -nosyslog: Print messages to stdout and stderr instead of syslog (default false)
* -wpanic: Make warning messages fatal (used for testing)
* -d: Alias for -debug
* -q: Alias for -quiet
v0.8, 2016-01-23
- Redirect output to syslog when running in the background
- New command-line option:
-memprofile: Write a memory allocation debugging profile the specified
file
v0.7.2, 2016-01-19
- Fix performance issue in small file creation
v0.7.1, 2016-01-09
- Make the
build.bashscript compatible with Go 1.3 - Disable fallocate on OSX (system call not available)
- Introduce pre-built binaries for Fedora 23 and Debian 8
v0.7, 2015-12-20
- Extend GCM IV size to 128 bit from Go's default of 96 bit
- New command-line option:
-gcmiv128: Use 128-bit GCM IVs (default true)
v0.6, 2015-12-08
- Wide-block filename encryption using EME + DirIV
- New command-line option:
-emenames: Enable EME filename encryption (default true)
v0.5.1, 2015-12-06
- Fix a rename regression caused by DirIV and add test case
- Use fallocate to guard against out-of-space errors
v0.5, 2015-12-04
- Stronger filename encryption: DirIV
gocryptfs.diriv
* This makes it impossible to identify identically-named files across
directories
* A single-entry IV cache brings the performance cost of DirIV close to
zero for common operations (see performance.txt)
* This is a forwards-compatible change. gocryptfs v0.5 can mount filesystems
created by earlier versions but not the other way round.
- New command-line option:
-diriv: Use the new per-directory IV file name encryption (default true)
* -scryptn: allows to set the scrypt cost parameter N. This option
can be used for faster mounting at the cost of lower brute-force
resistance. It was mainly added to speed up the automated tests.
v0.4, 2015-11-15
- New command-line options:
-plaintextnames: disables filename encryption, added on user request
* -extpass: calls an external program for prompting for the password
* -config: allows to specify a custom gocryptfs.conf path
- Add
FeatureFlagsgocryptfs.conf parameter
-plaintextnames.
- On-disk format 2
v0.3, 2015-11-01
- Add a random 128 bit file header to authenticate file->block ownership
- On-disk format 1
v0.2, 2015-10-11
- Replace bash daemonization wrapper with native Go implementation
- Better user feedback on mount failures
v0.1, 2015-10-07
- First release
- On-disk format 0
