PSST Cryptographic Information
PSST II employs known and respect cryptographic ciphers to protect your
privacy.
If you want to study the implementation in detail, download the Linux version
(which contains the Python source files - exactly the same files as are
used to construct the Windows version).
Generally speaking, PSST uses RSA public keys for session key exchange
and verifying session key security. The session cipher employed is
256-bit Blowfish, running in Cipher Block Feedback (CFB) mode.
The RSA keys are used with blinding mode, to protect against known plaintext
and other attacks where RSA is vulnerable to analysis with small data
payloads.
The low level encryption and decryption are performed by the
OpenSSL libcrypto
library.
Protocol Summary
Here's a quick overview of the key generation, session establishment and
authentication that PSST uses:
- Generate an RSA public key - This is what happens the first
time you run PSST, when the wizard prompts you to generate your keys.
Recall from the wizard that the key strength is selectable, from 1024-bit
through to 4096-bit.
The RSA public and private keys, once generated, are stored in your
PSST configuration file - psstConfig.dat. On Windows systems,
this file is stored alongside the PSST program files (wherever you
installed these). On *nix systems, psstConfig.dat is written to and
read from your user home directory.
- Exchange Public Keys with Other Users
PSST lets you export your public key, and import other users' public
keys. The public keys you import are also stored in psstConfig.dat
- Connect to other user (or allow them to connect to you -
Establishing a direct TCP connection is the first step.
From here on, the authentication and session establishment protocol
is completely symmetric - for everything you send to the other user,
the other user will send something equivalent to you.
- Send a hash of your public key. PSST then hashes your public
key against the other user's public key, and sends this to the other
user. If this hashed key doesn't match any hashes of public keys that
the other user has, the other user will terminate the connection
immediately.
- Create a Session Key and IV - Given that the other user has
confirmed your public key, PSST on your system will generate a 256-bit
Blowfish session cipher, plus a 128-bit IV (refer literature on
Blowfish encryption). Both of these are (of course) also encrypted
against the other user's public key.
- Sign the Session Key and IV - After sending the encrypted
session key and IV to the other user, PSST on your machine then hashes
these values, signs them with your private key, breaks up the
signature into chunks, encrypts these chunks against the other user's
public key, and sends these encrypted chunks to the other user.
- Verify Session Key/IV - If the other user fails to verify
the signature of the Session Key and IV you have sent, the session
is immediately terminated.
This signature verification phase is crucial, since it provides potent
defence against man in the middle attacks (whereby an attacker
intercepts the connection and substitutes their own session keys and
IVs in both directions, thus invisibly gaining access to cleartext
session traffic). If such an attack is taking place, and you've received
a substituted session key or IV, then the signature won't verify.
This is the reason why PSST is programmed to require public keys
shared in advance.
- Conduct the session - If the session hasn't been closed on
either end, then it means that the keys have been exchanged and validated,
and there is no man-in-the-middle attack in progress. The session at
this point is secured, and plaintext data can be exchanged in both
directions encrypted through the Blowfish stream.
Why Separate Session Keys - Why not just use Diffie-Hellman?
It occurred to me that if an attacker has archived the raw session traffic,
then compromised the private key on one side, they'll gain access to the
full session plaintext.
Therefore, I've opted to have two symmetric ciphers per session - one
for sending, and one for receiving.
The way the protocol is implemented, if an attacker gains access to your
private key, they'll only be able to decrypt data that you've received,
but won't be able to decrypt data that you've sent. This could make
all the difference in the world.
If you have any suggestions about how this encryption can be even further
improved, please get in touch..