Skip to content

Commit

Permalink
Added support for asymetric key based encryption
Browse files Browse the repository at this point in the history
  • Loading branch information
Zi1mo5zo committed Nov 22, 2018
1 parent ef36616 commit 6ae3a56
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 24 deletions.
56 changes: 42 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,52 @@ not, over HTTPS thanks to IPFS gateways, decrypt it and save it locally.

## Parameters

The default password length (`40` alphanumeric) and IPFS gateway ([Cloudflare's
gateway](https://cloudflare-ipfs.com)) can be overridden by setting the
environment variables `IWPASSWORDLENGTH` and `IWIPFSGATEWAY`, respectively.
The default behavior/settings can be modified by environment variables.

E.g.:
### Password length (sender only)

- `IWPASSWORDLENGTH=50 ipfs-wormhole.sh send FILE` will use a longer password to
encrypt FILE.
- `IWIPFSGATEWAY=https://gateway.ipfs.io/ipfs ipfs-wormhole.sh receive TAG` will
retrieve the encrypted file through the official IPFS gateway if the IPFS
daemon is not running.
`IWPASSWORDLENGTH=<int>` can be used to set the length of the temporary password
used by the symmetric encryption (default: `40`).

e.g.: `IWPASSWORDLENGTH=50 ipfs-wormhole.sh send FILE` will use a longer
password to encrypt FILE.

Note: Temporary passwords are limited to alphanumeric characters to be easily
added to the `gpg` command line and to the `tag`.

### Asymmetric (key-based) encryption (sender only)

`IWKEYBASEDENCRYPTION=<whateveryouwant>` can be used to replace the default
symmetric encryption by `gpg`'s key-based asymmetric encryption. This removes
the need for a secure side channel to send the `tag`, as the encrypted content
can only be decrypted by the private key of the recipient(s) (a password still
appear in the `tag`, but is useless).

This is the most secure mode but is less easy to use than the symmetric
encryption mode, that's why the latter is the default.

e.g.: `IWKEYBASEDENCRYPTION=whateveryouwant ipfs-wormhole.sh send FILE`, the
usual `gpg` prompt will ask you to choose the public key(s) of the recipient(s).

Note: No specific configuration is required on the client side, as `gpg` is
smart enough to ask for your passphrase if necessary.

### Fallback IPFS gateway (recipient only)

`IWIPFSGATEWAY=<url>` can be used to set the fallback IPFS gateway, if the
recipient's machine does not have `ipfs daemon` running (default: [Cloudflare's
gateway](https://cloudflare-ipfs.com)).

e.g.: `IWIPFSGATEWAY=https://gateway.ipfs.io/ipfs ipfs-wormhole.sh receive TAG`
will retrieve the encrypted file through the official IPFS gateway if the IPFS
daemon is not running.

# How it works

Your data is encrypted on the sender's machine, using `gpg` and its default
symmetric cipher (which depends on your specific `gpg` configuration), with a
temporary random password generated by `pwgen`.
temporary random password generated by `pwgen`. Asymmetric (key-based)
encryption is also supported, see 'Parameters' for details.

Once encrypted, your data is made available to others from your machine using
[IPFS](https://ipfs.io).
Expand All @@ -71,11 +100,10 @@ On the recipient's machine, the encrypted data is retrieved:

The encrypted data is subsequently decrypted on the recipient's machine with the
password (extracted from the tag), and saved with the proper file name (also
extracted from the tag).
extracted from the tag). When the asymmetric (key-based) encryption is used, the
private key of the recipient will be used to decrypt the file.

Confidentiality is not an issue as long as you trust `gpg`, its default
symmetric cipher (it's up to you to change it in `gpg`'s configuration file),
and `pwgen`.
Confidentiality is not an issue as long as you trust `gpg` and `pwgen`.

# FAQ

Expand Down
36 changes: 26 additions & 10 deletions ipfs-wormhole.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ function checkdep() {
}

case "${1:-}" in

send)
PWGENCMD="$(checkdep pwgen)"
TARCMD="$(checkdep tar)"
Expand All @@ -33,39 +34,51 @@ send)
PASSWORD=$($PWGENCMD -1 $IWPASSWORDLENGTH)
USERINPUT=${2:-}
FILE=${USERINPUT%/}
if [ -z "${IWKEYBASEDENCRYPTION-}" ]; then
GPGCMDOPTS="-c"
else
GPGCMDOPTS="-e"
fi
if ! pgrep ipfs 1>/dev/null 2>&1; then
echo "IPFS is not running, starting the daemon and sleep 5 seconds"
$IPFSCMD daemon &
sleep 5
fi
if [ "$GPGCMDOPTS" == "-c" ]; then
GPGCMDOPTS="--batch --passphrase=$PASSWORD $GPGCMDOPTS"
fi
if [ -d "$FILE" ]; then
TAG=$(
$TARCMD -Jc "$FILE" | $GPGCMD --batch --passphrase="$PASSWORD" \
-c -o - | $IPFSCMD add -Q
)
IFS=' '
TAG=$($TARCMD -Jc "$FILE" | $GPGCMD $GPGCMDOPTS -o - | $IPFSCMD add -Q)
IFS=$'\n\t'
FILE="$FILE".tar.xz
echo "Directory compressed and sent as $FILE."
elif [ -f "$FILE" ]; then
TAG=$($GPGCMD --batch --passphrase="$PASSWORD" -c -o - "$FILE" |
$IPFSCMD add -Q)
echo "File $FILE sent."
IFS=' '
TAG=$($GPGCMD $GPGCMDOPTS -o - "$FILE" | $IPFSCMD add -Q)
IFS=$'\n\t'
else
echo "error: $FILE is neither a file, nor a directory"
exit 1
fi
FILENAME="$(echo "$FILE" | base64)"
FULLTAG="$TAG-$PASSWORD-$FILENAME"
RECEIVECMD="$0 receive $FULLTAG"
echo "Retrieve it with $RECEIVECMD"
set +e
XCLIPCMD="$(command -v xclip)"
set -e
EXTRA=""
if [ -n "$XCLIPCMD" ]; then
echo "$FULLTAG" | $XCLIPCMD
echo "Copied to clipboard"
EXTRA="(copied to clipboard)"
fi
echo
echo "$FILE sent, tag: $FULLTAG $EXTRA"
echo
echo "Retrieve it with $RECEIVECMD"
echo
exit 0
;;

receive)
GPGCMD="$(checkdep gpg)"
USERINPUT=${2:-}
Expand Down Expand Up @@ -94,6 +107,7 @@ receive)
fi
exit 0
;;

checkdeps)
PWGENCMD="$(checkdep pwgen)"
TARCMD="$(checkdep tar)"
Expand All @@ -103,6 +117,7 @@ checkdeps)
echo "Everything looks good"
exit 0
;;

update)
WGETCMD="$(checkdep wget)"
echo Update...
Expand All @@ -111,6 +126,7 @@ update)
chmod +x "${0:-}"
exit 0
;;

*)
WGETCMD="$(checkdep wget)"
$WGETCMD -O- -q \
Expand Down

0 comments on commit 6ae3a56

Please sign in to comment.