One of the oldest still-working protocols on the Internet is FTP (File Transfer Protocol). Designed in the net’s earliest days, FTP never concerned itself with security. Later standards addressed this limitation by adding encryption, although insecure FTP remains in widespread use.
There’s FTP over SSL/TLS, which uses a digital certificate of the same type that secures Web sites—but which is hard to configure unless you run a server and can work through the configuration details at a low level. At one point, WebDAV plus HTTPS seemed like a solution: a WebDAV-enabled Web server allows file transfer and can offer the equivalent of FTP and HTTPS as a solution. But it’s funky to set up and also often requires direct Web server configuration access. (If your Web host provides it, however, consider using it!)
For many of us, SFTP (Secure FTP) turned out to be the best solution for secure file transfer. SFTP is not actually a secure evolution of FTP, but is instead part of the SSH (Secure Shell) remote access service. SSH replaced the Telnet remote login service (also unencrypted like FTP) with a more sophisticated, encrypted approach.
SFTP is often used with a password, but it can be set up to work with a pair of stored encryption keys. Making this relatively minor change improves your account security immensely: to log in to your server, someone would need to obtain a private key stored only on your computer. Nothing can be intercepted or extracted from your communications, and you can’t be fooled into revealing the key because you never enter it anywhere like you would a password.
If you have a hosting account that lets you access a Unix home directory for your account for file transfer, you should be able to set up SFTP with a private key without logging in via a terminal or command-line session at all. It’s a little easier to do in a terminal session, so I’ll show you that way too.
While some of the steps required to set up private-key access may seem daunting or technical, this is a one-time setup. Once you’re done, you won’t ever have to mess with it—or have weak security—again. (That said, if you buy a new Mac and don’t migrate your user account to it, you may have to repeat some of these steps; at best, you can just copy a file.)
Why switch from simple passwords to private-key access? Because the Internet is more scary and insecure than ever. Recently, someone broke into my hosted server and installed Bitcoin mining software. With nearly 30 years of experience managing Internet servers, you would think I had learned the necessary security lessons by now. The mistake was that I had long ago set my dad up with an account and password, and he probably reused the password years back on some other site, from which it was stolen. (There are no known hacks for the version of Linux I run or its supporting software that would allow a direct compromise. And only my dad’s account was cracked.)
As a result, I decided to disable all password-based terminal and SFTP sessions. It was an easy decision since I’m the only one who logs into the server remotely, and only a couple of family members need file transfer capability.
The steps to shift to private-key–secured connections are straightforward. I provide all the recipes you need to follow to create a paired set of encryption keys and copy the public key to the correct spot within your home directory on the server. As a bonus, if you log in via a terminal, those SSH sessions will now work password-free, too.
Step 1: Create a Set of Keys
The simplest form of key-based SSH authentication relies on public key cryptography, which creates two linked keys, one public, the other private. You must keep the private key secret and it should typically never leave your computer. You can freely share and even publish the public key. The public key can be used both to encrypt messages that only the possessor of the linked private key can decipher, but it can also be used to verify definitively that a message (or file or app) was digitally signed by the private key’s owner.
With SSH, you generate a public/private pair. The private key stays on your Mac; you copy the corresponding public key to your account on a server. When you start an SFTP (or SSH) session, your Mac and the SSH server on the server pass messages back and forth to prove each other’s identity to each other. That includes signing messages with their respective private keys that the other validates with the public key they possess for the other party.
This happens automatically; no management is required except when you first connect to the server, described in the next section. (When using SSH from the terminal, the ssh command-line app automatically tries the public keys first if the server accepts them.)
Here’s how to create the keys:
- Launch Terminal on your Mac.
- Type or copy the following exactly and press Return:
ssh-keygen -t rsa
- The ssh-keygen program prompts you for a location to save the file:
Enter file in which to save the key (/Users/gif/.ssh/id_rsa):. Press Return to save the file in a hidden
.sshdirectory inside your home directory. (You can specify a different path and name but that’s not necessary unless you’re creating multiple keys.)
ssh-keygenprogram prompts you to enter a passphrase. This isn’t needed and won’t interact well with most Mac file transfer apps. Press Return. When prompted to verify, simply press Return again.
A few lines of information appear that are only of interest to people working with others to use these keys; you can ignore them. Your keys are now generated as
id_rsa (the private key) and
id_rsa.pub (the public key).
If you use Panic’s Transmit, you can skip the steps above and generate a key directly within the app:
- Launch Transmit and choose Transmit > Preferences > Keys.
- Click the + at the lower-left corner and choose Generate Key.
- Name the key. Leave the format set to RSA. You can optionally increase the Size setting from 2,048 to 4,096 or 8,192. That increases the strength of the encryption, but 2,048 is fine. Don’t enter a passphrase.
- Click Generate.
- Click Copy Public Key for use in both sets of instructions below instead of copying the text from a file stored on your Mac.
If you connect from multiple Macs, you could repeat the procedure above and then copy each Mac’s public key to the server in the next section. However, if all your Macs are under your control, it’s secure enough to use the same key pair across all of them. Simply copy the generated
id_rsa.pub keys to each Mac: you can use a USB drive, a network connection, screen sharing, or what have you. You may need to create an
.ssh folder in
/Users/username/ on Macs that haven’t yet interacted with SSH.
With the keys generated, you can copy them to your server account.
Step 2: Transfer Your Public Key to Your Server Account
In this next operation, you copy the public key to your server. If you have only file transfer access:
- Use your file transfer app to view your home directory on the server, which is usually a path like
/home/glennfor a shortcut like
- In that view, create a directory named
.ssh(that’s ssh with a period before it).
- Use the app to set permissions on the directory to be owned by your account and only readable, writable, and executable (required to view the contents of a folder in Unix). Group and world permissions should all be off. (If you don’t see the
.sshdirectory, check the setting in your app to show hidden directories and files; items beginning with a period are often hidden in lists.)
- On your Mac, open the
id_rsa.pubfile in your .ssh folder. (In the Finder, you can press Command-G and then enter
~/.ssh/to navigate to that folder.) You should be able to open it in any text editor like BBEdit or even TextEdit.
- Copy the contents of
id_rsa.pub(an example is below this list) and paste it into a new text file.
- Name that second text file
authorized_keys(with no extension) and make sure it’s saved as plain text, not RTF or anything else.
- Via your file transfer program, navigate into your account’s
.sshdirectory and upload
- Set the file permissions for
authorized_keysto read and write by the owner only.
Here’s what a public key looks like:
If you’re comfortable with the command line, the necessary commands can be a little faster and simpler:
- Via a terminal app connected to the server, navigate to your home directory (
- Create an
~/.ssh/directory with the correct permissions (
mkdir -m 700 .ssh).
- On your Mac, open
~/.ssh/id_rsa.puband copy its contents.
- On the server, navigate into the
~/.ssh/directory or use your favorite command-line text editor to open or create a file called
- Paste the copied text into that file via the terminal session—since it’s text it will transfer correctly—and save it.
- Make sure the permissions on authorized_keys are set correctly by entering
chmod 0600 authorized_keys.
That’s the entire setup! Now you have to use a file transfer program that supports passing the SSH handshaking necessary. But first, a quick aside about validating that the server you connect to is the one it claims to be.
Dust for Digital Fingerprints
When you use any means to connect via SSH, including SFTP, the first time you connect to a given server, you will be asked to verify that its “fingerprint” is accurate. The fingerprint is an encrypted shorthand version (a hash) of the public key part of the server’s public/private keypair. In some apps, including Cyberduck, this abbreviated version displays as 16 sets of two-digit hexadecimal (base 16) numbers separated by colons—the outdated but still-used MD5 algorithm. It looks like this:
In other apps, such as Transmit, you’ll see what looks like a 43-character mix of text, letters, numbers, and punctuation (the SHA256 algorithm), but which represents the same source public key:
(Why 43 characters? It’s 256 bits of information, but divided into 6-bit pieces to represent values in a reduced character set—a kind of an abbreviated ASCII.)
The shorthand is used because the public key is quite long and you’re not trying to check slight differences between digits. You just want to know that the public key on the server you think you’re connecting with is identical to the public key offered by the server you’re connecting to!
On the first connection, your computer has no record of that key. If you agree it’s correct, it’s stored (also in the
~/.ssh/ directory) and matched in the future. You’ll only be warned again if it changes, which can be a sign to check that the server wasn’t compromised.
The fingerprint helps you resist man-in-the-middle (MitM) attacks. If someone can redirect your server’s domain name or somehow insert themselves on a network connection between you and the destination, they have a dilemma. They can fake the public key, but then they can’t respond correctly to your software’s handshake because they don’t possess your private key. Your file transfer software will flash alarms or at least note an error.
If the attacker instead generates their own keypair, the fingerprint won’t match and you have to be alert to notice the error. If you don’t notice it, the MitM can present fake information or a fake file listing and try to convince you to engage in insecure behavior.
However, because the server has your public key stored, the MitM can’t access your account or files on the server: the server will always reject any connection attempt that doesn’t provide the private key that matches the stored public key.
In most cases, it’s not critical to check fingerprints because you’re not at risk of a MitM attack, and the attackers can’t extract your password or gain access to anything in the process except fooling you.
However, if you want to ensure you’re on the straight and narrow with the server:
- If your account is with a hosting service, see if they can provide their hashes (ask for MD5 and SHA256 versions) for their SSH server.
- If you have sufficient access on a hosted server or your own, you can run a command that produces the necessary hashes. It’s arcane but simple; read this article for the recipes.
You can now connect without using a password!.
Step 3: Configure Your File Transfer App
Many file transfer apps support SFTP connections with SSH-connected keys. These include two popular options: Cyberduck (macOS 10.9 or later, free but donation requested) and Panic’s Transmit (macOS 10.14 or later, $45).
In CyberDuck, here’s how to use a public/private keypair for login:
- Choose Bookmark > New Bookmark.
- Choose SFTP from the pop-up menu at the top.
- Give the bookmark a memorable nickname and enter the server name and your account username.
- From the SSH Private Key pop-up menu, choose your
id_rsakey if it’s not already selected.
- Close the bookmark entry and then double-click it in the bookmarks list to connect.
- You will likely see a fingerprint warning. Click Allow if you’ve checked or are comfortable proceeding. Check Always to avoid this alert each time you connect after this while the fingerprint remains unchanged.
In Transmit, the process goes like this:
- While in the Servers view in any pane, choose Servers > Add New Server.
- Name the server descriptively, choose SFTP (it may already be chosen by default), and click Next.
- Enter the server name in the Address field and your account username in the User Name field.
- If you’re using a key generated within Transmit, click the key icon to the right of the Password field and select it from the list. If you’re using the default key in the
~/.ssh/directory as described earlier, you don’t need to select anything: Transmit automatically uses any keys in
~/.ssh/when it tries to connect.
- Click Save.
- Double-click the entry to connect.
- If a fingerprint prompt appears, examine it and click Connect if it matches your expectation.
That’s it! From now on, all your file transfer connections will be more secure than they would be with a password, and you won’t have to enter or manage a password.
Forward into the Future
Security is a constantly escalating battle, and passwords are increasingly targeted. Upgrading your security for SFTP (and SSH sessions if you use them) reduces a significant potential point of weakness. While SSH isn’t perfect, the use of strong encryption keys improves your security today and into the foreseeable future.