In what format is the public key of a server stored in the known hosts? - ssh

When we ssh to a host, he is either known or not. In the latter case during our first try to connect we are prompted to
The authenticity of host '13x.8x.xx.1x1 (13x.8x.xx.1x1)' can't be established.
RSA key fingerprint is xx:xx:xx:xx:xx:26:86:80:5f:17:xx:xx:xx:xx:6d:6c.
Are you sure you want to continue connecting (yes/no)? yes
Then the server's RSA public Key is stored in the .ssh/know_hosts file. How is it encoded? And how can we ensure that this is not a man-in-the-middle?
Finally, this so-called 'host key' is assymetric. What does this mean?

How can we ensure this is not a man-in-the-middle?
The first time, you can check the RSA fingerprint. Someone needs to previously communicate it to you, or you need to somehow receive it securely (ie published via a https site, or received via a signed email). Many hosting providers, for example, send you your hosts SSH fingerprint.
On Ubuntu, you can find your own RSA fingerprint using:
ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
Note that there are other in-use fingerprint formats (dsa and ecdsa), depending on the server and client config. In your known_hosts file you can see the format in which each fingerprint has been stored.
How is it encoded?
The known_hosts file is a list of hostnames (or often, hashes of hostnames), the type of the fingerprint, and the fingerprint itself (cryptographic information) in base64 encoding. The format details can be found in the OpenSSH man page, under the SSH_KNOWN_HOSTS FILE FORMAT section.
This so-called 'host key' is asymmetric. What does this mean?
These asymmetric mechanisms mean that while the fingerprint allows you to verify the identity of the server, you cannot use it to generate a valid identification (to impersonate) that server.
It must be noted that the fingerprint (and the corresponding private key) are used as secret for cryptographic operations: a random challenge is sent from the client to the server. The server, which has the private key, can sign that challengue and send it back, then the client can verify the signature is valid because the fingerprint is appropriate.
In other words, the cryptographic secret is two-fold, the private key can cipher or sign, and the public key can be used to decipher or verify a signature. One of the keys can be made public at no risk, and used to verify signatures and to cipher text that only the owner of the private key will be able to decode. This is roughly what asymmetric means in cryptography.

Related

How is ECDSA used for key exchange?

When you go to google.com, the certificate under "Subject Public Key Algorithm" shows:
Elliptic Curve Public Key
ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256)
Key size: 256 bits
which apparently is ECDSA. I thought ECDSA is used only for signing/signatures and not
for key exchange. What am I missing?
The key doesn't restrict this. Most elliptic-curve keys (leaving out Bernstein) including this one technically can be used for ECDSA signing, ECDH or ECMQV key agreement, or ECIES encryption. The encoding was established by X9.62 because that was the first issued, but the same curves, key values and encoding are used by the other operations. (Many applications also use the point encoding first created by X9.62, but there is some variation there.)
But the cert does. The cert (also) has the KeyUsage extension set to digitalSignature (and the ExtendedKeyUsage extension set to id-kp-serverAuth). This means when used in TLS it can only be used for ECDSA signing to authenticate the server.
TLS/SSL often uses sign-only certs. Most TLS connections nowadays use 'ephemeral' keys (not in a certificate) for key agreement combined with signing by a cert's key (or more exactly by the privatekey matching a publickey cert) for authentication of the server, and optionally but rarely authentication of the client. This provides (Perfect) Forward Secrecy which means that even if a server privatekey is later compromised, recordings of previous sessions cannot be decrypted so their content remains safe (at least from this attack; SSL/TLS only covers transport and never protects against compromise at either endpoint, during or after the session). In the early days of SSL people often didn't bother with PFS, but after Snowden made lots of people aware of mass surveillance programs -- especially non-techie people like managers and bosses and users and customers -- these options became much more widely required or recommended, and used.
For TLS1.0-1.2 (and SSL3, but you should no longer use that because it is broken) key agreement and signing (server authentication) are linked in the ciphersuite: all ciphersuites that use an ECDSA cert for server auth use ECDHE key agreement, and all ciphersuites that use (integer) DSA* cert for server auth use (integer) DHE key agreement; the E in DHE and last E in ECDHE are for ephemeral. Since RSA supports both signing and encryption, an RSA cert key can be used for key transport (encryption) but this is no longer recommended, or it can be used to sign either kind of ephemeral key agreement. (* For hysterical raisins SSL/TLS standards use DSS to mean DSA.) For TLS 1.3 these algorithms are now selected separately, but use of some ephemeral key agreement is practically required on the public net, and use of some signing cert is required nearly always, so they will probably be used in the same combinations as now except RSA-only key encryption is no longer allowed.
See:
https://security.stackexchange.com/questions/20803/how-does-ssl-work (the Great Ursine Epic)
https://security.stackexchange.com/questions/3638/security-of-pki-certificates-certificate-authorities-forward-secrecy
https://security.stackexchange.com/questions/8343/what-key-exchange-mechanism-should-be-used-in-tls
https://security.stackexchange.com/questions/35471/is-there-any-particular-reason-to-use-diffie-hellman-over-rsa-for-key-exchange

How to gpg encrypt with ssh public key?

I have a public key in a file called key.pub, and the contents look like:
ssh-rsa AAAAB...<snip>...t+f klahnakoski
I would like to to use it to encrypt a file with gpg. What is the sequence of shell commands required?
I imagine the sequence looks something like:
convert key to gpg-friendly format
invent some credentials to sign key with
invent a user to facilitate adding key to keyring
perform the encryption
Thank you!
RSA keys can only be used to encrypt a proportion of their key length. e.g. a 2048 bit RSA key can only be used to encrypt about 245 bytes.
See:
https://security.stackexchange.com/questions/33434/rsa-maximum-bytes-to-encrypt-comparison-to-aes-in-terms-of-security
So to encrypt / decrypt large amounts of data (files) you would use a symmetric key which was encrypted using a public key, not the public key itself.
Also, you wouldn't add a symmetric key to a public SSH key, because the the symmetric key is a secret, and the public SSH key isn't a secret. The symmetric key should be added to the private SSH key.
It goes something like the following:
To convert the file format, install the monkeysphere tool set (Ubuntu)
sudo apt-get install monkeysphere
Use the pem2openpgp tool to convert the private key to gpg format. Pipe to gpg for import.
pem2openpgp userid-ssh#example.com < id_rsa | gpg --import
# Check it's there
gpg --list-secret-keys
Edit the trust level you have in the key.
gpg --edit-key userid-ssh#example.com
gpg> trust
Add the trust level you need (ultimate for example)
The key imported is only suitable for creating certificates, not for signing or encryption.
Encryption
The key is an RSA key and can't be used to encrypt / decrypt large amounts of data. If you want to do that you have to add a symmetric encryption subkey. When you encrypt, GPG will use this subkey rather than the original SSH key.
gpg> addkey
Please select what kind of key you want:
(3) DSA (sign only)
(4) RSA (sign only)
(5) Elgamal (encrypt only)
(6) RSA (encrypt only)
Your selection? 6
Now you can encrypt and decrypt using the identity based on the SSH key.
gpg -vv -r userid-ssh#example.com -e -a unencrypted_file.txt
So how useful is this?
Well, it makes more sense to use GPG to generate and manage your SSH keys as authentication subkeys rather than trying to do it the other way round. In fact it can be integrated into SSH instead of ssh-agent.
Probably ssh-vault could give you some ideas, it follows the same principle of PGP and using the public ssh keys to encrypt the password only.

How to decrypt encrypted application data in wireshark?

I have some HTTPS/SSL packets between client and the server. I need to decrypt the application data after the SSL handshake. I have a SSL server key as well. I configured wireshark to take the private key like shown below.
I went to EDIT-> Preferences-> protocols->SSL -> Add private key to RSA key list.
I have a JKS keystore configured on the server and I converted it to PKCS format and gave in wireshark. But still I am not able to decrypt the data . Please help

SSL: Server key length and browser connection info. Base understanding

I'd like to understand something.
I generate keys with xca, which is a UI to openssl.
I have created a CA, then generate a server certificate for https and use this CA to sign the generated certificate. The newly created certs are subcerts of the CA (as far as I can tell).
I put in the CN for the domain, generate a new private key of 4096bit length, export the crt and key pem including private key. Upload and configure nginx in this case.
Now I'm accessing the site over https. When clicking connection info in Firefox I see:
Connection Encrypted: High-grade Encryption (TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 128 bit keys)
In Chromium:
Your connection to domain.tld is encrypted with 128-bit encryption. <...>
The question/s:
My private key is 4096 bits. Why does it use 128 bits?
Which of the 4096 bits are used in those 128 bits?
Why am I generating a 4096 bit key if only 1/32 of its length are used?
I'd like to understand how this process works.
The 4096 bit RSA key and its associated certificate provides authentication during the setup of the connection and key agreement, allowing the client to verify that they are indeed connected to your server, and not a man-in-the-middle claiming to be your server.
However, the RSA algorithm is orders of magnitude slower than symmetric algorithms like AES with similar security properties, as well as being limited in the amount of data it can encrypt. It is therefore not used to protect the actual data transmitted, and instead a session key for a symmetric algorithm is agreed between the client and server.
In this case, the session key is agreed using the ephemeral Elliptic Curve Diffie-Hellman (ECDHE) algorithm, which allows client and server to derive a random, shared key without ever transmitting the key itself. It is this key which is 128bit, and is being used with the symmetric AES encryption algorithm in Galois/Counter Mode (GCM).

OpenSSL and s_client - why is a private key required from the client?

I need to setup a 2 way SSL communication channel between a .NET/WCF application and a third party web server. Right now I am trying get a successful handshake with the host in order to validate that all the elements are setup correctly (client certificate, server certificate authority, network communication...). I'm using the openSSL command line tool to try and validate this, using the s_client command.
Here is what is stopping me, and what I don't understand:
whatever I do, openSSL is expecting to find a private key for the
client certificate
the client certificate was given to me by the third party, but it
does not contain any private key
if I just generate my own private key file using openSSL, I'm getting
a key values mismatch error
Keep in mind that I have just started getting my hands into SSL so I have a very basic understanding of the whole protocol. From what I've been reading, it seems that both server and client need their private key in a 2 way SSL setting. However, I can't figure out how to get a working private key on my client (working with the client certificate that was given to me).
I would very much appreciate if somebody could shed some light on client certificate private keys, as this is giving me a major headache.
Certificates on their own are only public pieces of information. What links a public key certificate to the name it contains is the fact that whoever has legitimate control over that name (e.g. your name or your server's name) also has the private key for it.
Certificates are used to prove the identity of the remote party by challenging the remote party to perform an operation that can only be done with the corresponding private key: signing something (which can be verified with the public key) or deciphering something that was encrypted with the public key. (Both can happen in the SSL/TLS handshake, depending on the cipher suite.)
During the SSL/TLS handshake, the server sends its certificate (in clear) and proves to the client that it has the corresponding private key using an authenticated key exchange.
In your case, you also want to use client-certificate authentication. It's not enough to send the client certificate during the handshake: the client must also prove it has the private key. Otherwise, anyone who receives that certificate could clone it. The point of using certificates is to prevent any cloning, in such a way that you never have to show your own secret (the private key).
More specifically, the client has to sign the handshake messages in the Certificate Verify message of the TLS handshake so that the server can verify it against the public key sent in the client certificate. Without this step, no client-certificate authentication would be taking place.
the client certificate was given to me by the third party, but it does
not contain any private key
Giving you your certificate without its private key seems a bit pointless, unless you're expected to have generated a certificate request on your side beforehand (in which case you would have the private key).
Indeed, rather than being given a certificate and its private key, it's better practice for you to generate your key-pair, create a certificate request (CSR), and have your CA issue a certificate from that CSR (but without them ever knowing your private key). In this case, you would be expected to have kept your private key, and you would be able to use it with the cert you would have received.
This is an interesting question. I was puzzled by TLS related errors while configuring LDAPS, my learnings here.
The names, "public key" and "private key" sound like it's an one-way operations, but it works both ways, anything encrypted by one key and be decrypted by another key - just that one key is made public
Info = openly available data, with unknown integrity - it could be tampered by 3rd party
Signature = Info encrypted by a private key, accompanies Info
Verifying signature = use public key to decrypt the signature and get Info back thus proving "whoever created the signature knows the private key", or, the Info is untouched after it's signed
That is, unless the private key is stolen
Certificate = Info + Signature + public key + private key
Info = the meat
Signature = to verify integrity of Info
public key = to verify other certificates, see Certificate Chain
private key = not included in certificate itself but should be kept by certificate owner, could be used to sign other certificates
Certificate Authority (CA) = Anyone who holds a public / private key pair and creates certificates
CA identity is indicated in Info on a certificate
Certificate Chain = Use public key on mother-certificate to verify the signature on a child-certificate, to ensure child-certificate was created and signed by mother CA
And mother created and signed by grandma, so forth
Root CA = Root CA is the CA you trust unconditionally
Because their certificates (Root Certificates) are pre-loaded in your browser or OS as a source of trust
Also because their certificates are self-signed, its Signature is created using its own private key, verified by its own public key
This could be confusing, but think it as the origin of certificate-based encryption - only when people found out that relying on a few Root CA's to create and sign countless certificates are insecure (private keys might get stolen) and impossible (rapidly increasing demands of certificates), they came up with the idea of certificate chains
Root CA's only create and sign certificates for some Intermediate CA's so private keys are not used too often and is safer
Intermediate CA's can create and sign millions of certificates and get their certificate revoked when a private key is known to be leaked
This is the reason you don't often see the Root Key Ceremony, which signifies the importance of the private key for a Root Certificate: the less the private key is used, the less it could be exposed
Self-Signed Root Certificate = virtually the same as a Root Certificate - just no one but the creator would trust
TLS Handshake = server sends certificate, client validate is against the certificate chain, when verified, exchange a "password" securely
The "password" is then used to encrypt actual data transfer using symmetric encryption
Asymmetric encryption is not used for actual data due to its need for intense computation powers
Client Certificate Authentication = in addition to previous process which authenticates the server, the server demands a valid certificate to be provided by the client, also a signature of previous handshake messages
The signature is created using the private key of the certificate and can be verified by the public key on the certificate
This proves the ownership of the certificate
This is used usually for restricting access to known individual clients
Using certificates means no man-in-the-middle or replay attack could happen
This is often seen in finance or IoT
This is also utilized by LDAPS, which caused mystic error messages when I had a valid certificate in my local keystore but it was not accompanied by its private key
...So, in terms of openssl, when you use -cert you indicate Client Certificate Authentication, with which you will need -key to specify the corresponding private key.
However, for many Web scenarios, even if the certificate for a server is signed by a homemade CA, one only need to add the homemade CA to truststore or keychain then server certificate can be validated. This is done by using -CAfile.
Bottom-line.. If you're sending client certificates, then you would need the client certificates' private key to encrypt the pre-master secret