Does phpseclib checking SSH fingerprints? - ssh

Long time ago, phpseclib was not checking SSH fingerprints. Does phpseclib now implement checking SSH fingerprints?

phpseclib has always had the ability to check fingerprints via the $ssh->getServerPublicHostKey() method. That method verifies that the host key is valid for the host and, if so, returns the host key for you to either save locally (be it to the DB or filesystem or whatever) or to check against the host key that you already have on file.
phpseclib has had this since the first release (0.1.0), which was over 10 years ago:
https://github.com/phpseclib/phpseclib/blob/0.1.0/phpseclib/Net/SSH2.php#L1586
https://github.com/phpseclib/phpseclib/blob/0.1.0/phpseclib/Net/SSH2.php#L745
In the initial release the signature would be checked regardless of whether or not you retrieved the host key. Now, the signature is only checked if you retrieve the host key.
That said, phpseclib's Crypt_RSA class didn't always have a getPublicKeyFingerprint() method:
https://github.com/phpseclib/phpseclib/blob/1.0.10/phpseclib/Crypt/RSA.php#L1850
Maybe that's what you're thinking of but if so that's completely irrelevant. The reason they exist is because of the following scenario:
You connect to a server, get the host public key and create a finger print from that. You call the operator of the server up and check your finger print with them. In the case of a 1024-bit RSA key it's more convenient to read someone 32 hexadecimal characters than it is to read someone 256 hexadecimal characters.
But then again, do you see yourself actually physically calling up the operator of an SSH server anyway?

Related

Apache Mina Client Public key authentication

apache mina sshd authenticate client signatures
I found this link, I have implemented the PublicKeyAuthenticator's authenticate method and using KeyUtils.compareKeys method to compare the public key of the user stored and the incoming key. But its not matching. What is the format of the key that needs to be stored in the local to compare against the incoming public key? I have been breaking my head on this for the last few weeks and couldnt solve this. Please help.
I think the key should start with -----BEGIN RSA PRIVATE KEY----- to be recognizable by Apache Mina.
If you are using putty gen key, which starts with PuTTY-User-Key-File-2: ssh-rsa, there should be some tweaks to be made to work with these files,
something like:
PuttyKeyUtils.DEFAULT_INSTANCE.loadKeyPairs(Paths.get(privateKey), FilePasswordProvider.of(this.pwd)))
put a breakpoint on compareKeys() in KeyUtils, you will be able to see the keys being compared and try to find their type. I had a similar problem and for me turns it was not able to compare OpenSshCertificate type of public key.

AWS S3 SSE GetObject requires secret key

The idea was to generate a random key for every file being uploaded, pass this key to S3 in order to encrypt it and store the key in the database. Once the user wants to access the file, the key is read from the database and passed to S3 once again.
The first part works. My objects are uploaded and encrypted successfully, but I have issues with retrieving them.
Retrieving files with request headers set:
When setting the request headers such as x-amz-server-side-encryption-customer-algorithm etc. when performing the GET request to the resource, works, and I am able to access it. But since I want to these resources as src to an <img>-Tag, I cannot perform GET requests which require headers to be set.
Thus, I thought about:
Pre signing urls:
To create a pre signed url, I built the HMAC SHA1 of the required string and used it as a signature. The calculated signature is accepted by S3 but I get the following error when requesting the pre signed URL:
Requests specifying Server Side Encryption with Customer provided keys must provide an appropriate secret key.
The URL has the form:
https://s3-eu-west-1.amazonaws.com/bucket-id/resource-id?x-amz-server-side-encryption-customer-algorithm=AES256&AWSAccessKeyId=MyAccessKey&Expires=1429939889&Signature=GeneratedSignature
The reason why the error is shown seems to be pretty clear to me. At no point in the signing process was the encryption key used. Thus, the request cannot work. As a result, I added the encryption key as Base64, and Md5 representation as parameters to the URL. The URL now has the following format:
https://s3-eu-west-1.amazonaws.com/bucket-id/resource-id?x-amz-server-side-encryption-customer-algorithm=AES256&AWSAccessKeyId=MyAccessKey&Expires=1429939889&Signature=GeneratedSignature&x-amz-server-side-encryption-customer-key=Base64_Key&x-amz-server-side-encryption-customer-key-MD5=Md5_Key
Although the key is now present (imho), I do get the same error message.
Question
Does anyone know, how I can access my encrypted files with a GET request which does not provide any headers such as x-amz-server-side-encryption-customer-algorithm?
It seems intuitive enough to me that what you are trying should have worked.
Apparently, though, when they say "headers"...
you must provide all the encryption headers in your client application.
— http://docs.aws.amazon.com/AmazonS3/latest/dev/ServerSideEncryptionCustomerKeys.html#sse-c-how-to-programmatically-intro
... they do indeed actually mean headers and S3 doesn't accept these particular values when delivered as part of the query string, as you would expect, since S3 sometimes is somewhat flexible in that regard.
I've tested this, and that's the conclusion I've come to: doing this isn't supported.
A GET request with x-amz-server-side-encryption-customer-algorithm=AES256 included in the query string (and signature), along with the X-Amz-Server-Side-Encryption-Customer-Key and X-Amz-Server-Side-Encryption-Customer-Key-MD5 headers does work as expected... as I believe you've discovered... but putting the key and key-md5 in the query string, with or without including it in the signature seems like a dead end.
It seemed somewhat strange, at first, that they wouldn't allow this in the query string, since so many other things are allowed there... but then again, if you're going to the trouble of encrypting something, there seems little point in revealing the encryption key in a link... not to mention that the key would then be captured in the S3 access logs, leaving the encryption seeming fairly well pointless all around -- and perhaps that was their motivation for requiring it to actually be sent in the headers and not the query string.
Based on what I've found in testing, though, I don't see a way to use encrypted objects with customer-provided keys in hyperlinks, directly.
Indirectly, of course, a reverse proxy in front of the S3 bucket could do the translation for you, taking the appropriate values from the query string and placing them into the headers, instead... but it's really not clear to me what's to be gained by using customer-provided encryption keys for downloadable objects, compared to letting S3 handle the at-rest encryption with AWS-managed keys. At-rest encryption is all you're getting either way.

which machineKey config is better?

i 'm working on my web application security and want to know if i use this:
<machineKey validationKey="AutoGenerate,IsolateApps"
compatibilityMode="Framework45" decryptionKey="AutoGenerate,IsolateApps"
validation="SHA1"/>
in my web.config , now first user send first request to my site and in this time validationKey will be create and after that second user send second request now validationkey will be create again or what ?
and are the same these validations keys for all user ?
what is deference between that config and this?
<machineKey compatibilityMode="Framework45"
validationKey="37BAD4B702C65CF39B1ED514AC4B3D88990DDF784AA0895659
B528ED95F8CA0A9CD1AF5ED92A2599362684CB8D204AC30D07E6BF0CF65194A5129"
decryptionKey="B450FB3271C49E6BA89A0C5C8D06B61875BCE4916A40474ED"
validation="SHA1" decryption="AES" />
which one is better to use?
AutoGenerate means that your key is auto generated once and then stored (by the Local Security Authority service) - in other words, it doesn't change between requests - in fact, it should never change on the same machine.
IsolateApps means each application (ETA: mostly, see below) gets its own validation/decryption key - rather than all applications on the machine sharing a single key. But still, the key is generated and then stored the first time it's needed, and will be reused for all subsequent requests.
Update 2017: ASP.NET 4.5 added IsolateByAppId, which adds further isolation compared to IsolateApps. IsolateApps creates a different key for each app based on it's virtual directory path. This means that if two apps on the same server have the same virtual path (e.g. /), only being distinguished by being hosted on different ports or host name, they'll still get the same key, even with IsolateAppsenabled. IsolateByAppId will create different keys based on the application's AppDomainAppID. (End of update)
However, if your application is hosted on a web farm, in the cloud, on a cluster, etc. - where requests may be processed by different machines, you'll need the key to be the same for all those machines - hence the pre-generated keys in your second example. Do remember that you need to generate these yourself (and generate them properly), rather than reusing someone else's.
Here's an easy way to generate the keys with IIS 7
ETA: To avoid link rot, here's a synopsis of the link above: IIS 7 and later includes machine key generation in the IIS Manager UI: Under Machine Key for your website (found in the ASP.NET section), you'll find a Generate Keys action in the actions panel. This uses the RNGCryptoServiceProvider to generate decryption and validation keys for you.
(Once upon a time, apparently the SQLMembershipProvider would complain about auto generated keys - but only in order to avoid the above issue if the application should end up not hosted on a single server).
Microsoft recommends using the default values if the above situation doesn't apply to you - i.e.:
If your application is hosted on a single server: Use AutoGenerate,IsolateApps
If your application is on a web farm/cloud service/clustered network: Use a manually generated key.
(You're also specifying "AES" as the decryption algorithm in the second example, but since AES is the default, that's not a difference between the two).
Update 2017: Why would I want to use IsolateApps (and/or IsolateByAppId)?
The question should really rather be, why wouldn't you? It's on by default. The reason being that a host without it and hosting multiple applications, every application would get the same key, which isn't the best scenario, if you're not in control of all applications (e.g. a shared host).
Does it have downsides (other than being useless for web farm/cloud/cluster)? Yeah, somewhat. IsolateApps will reduce the entropy of the dncryption key by 32 bits (from 192 bit to 160), because 32 bits of the key will be a hash of your virtual directory, which is known to an attacker (for example, if your app is at the root of the domain, those 32 bits will be 4e ba 98 b2. IsolateByAppId reduces it further by another 32 bits to 128 bits.
That leaves you with what (basically) amounts to 128 bit AES rather than 192 bit AES for the decryption key. Similarly, the validation key will be reduced from an entropy of 256 bits to 192 bits.
Disclaimer: The following paragraph is a dangerous thing to say in cryptography, so do research it further rather than trusting it if you're doing security critical work - and particularly if you're using the keys for data with information value beyond the next decade.
Anyway: If you don't know the implications of the above entropy reductions, those implications are unlikely to bite you. 128 bit security with AES and 192 bit entropy for the validation key (a hash) is, in 2017, more than "good enough". (Hence why this is not thoroughly documented in the first place). (End of update)

Multiple SSH public keys into a single file

I'm trying to sftp to a host which acts as a load balancer and routes to 3 other systems based on round robin.
Our public key is setup on their systems. Yet, when ever I try to connect, I get prompted with a "Man in Middle attack" message asking us to verify the key finger print. To over come this I tried adding their public host key into .ssh2/hostkeys/key22_22_hostname.pub file.
Problem is I can't add 3 keys into this file, it seems to accept only one key?
Any suggestions on how to overcome this issue or add 3 public keys into one key22_22_hostname.pub file?
This is on AIX system.
How about cheat and copy the one system's keys to the others? I know is sorta scummy but in this case, it might be appropriate.
I believe those keys are found in /etc or maybe /etc/ssh.

Security from evil User

My X system uses public key to decrypt a cipher and do some work based on that. But user of the system whom i do not trust has access to the system, cipher and the key.
So what he can do is change the cipher, create another set of keys encrypt using private key and replace the cipher and public key both. So next time system will not know that message has change. I basically do not care if user can read it, my problem is he can not change it, so i thought of a MAC unfortunately that evil user can change the MAC as he has the access to the repository.
Big problem is that user going to always have unlimited access to cipher and the key(s) now how i can secure the whole thing?
Your problem appears to be one of key management. How do client programs obtain the server public key? Do they ask the server directly? Or do they get the server public key from some other independent source? Wouldn't the client become suspicious if the public key changed one day without notice?