I want to use asymmetric encryption of headers in RESTful requests to verify the identity of the system sending the request: i e System A encrypts it's name, timestamp, and the service name using it's public key in a request to System B. System B then uses the public key of System A to decrypt, proving the authenticity of the request.
1) Does php-mcrypt support this?
2) Has anyone benchmarked this type of operation?
No, mcrypt is just symmetric block ciphers.
However the PHP OpenSSL extension supports asymmetric operations. The ones you want are openssl_sign and openssl_verify.
(You have a slight terminology issue - in asymmetric systems, encryption is done with public keys and decryption with private keys; signing is done with private keys and verification with public keys. Do not confuse signing with encryption or decryption - although the underlying operations are often similar, it is not the same thing, and the confusion can lead to insecure implementations).
Of course, you could just do your REST over SSL, using client certificates for authentication.
Related
I'm putting together an android client (and possibly in the future iOS, web portal, etc) and php mysql server. Server side I am currently using the PHPass library to hash and salt the incoming passwords.
Should I make the client send plain text passwords over HTTPS/SSL or should the client do some form of hashing first. For example should every client simply sha1 (or some other algorithm) every outgoing password?
Most websites will send the password plain-text over an encrypted connection SSL/HTTPS. Hashing the password client-side can be done, but the advantage is small and often client-side languages (JavaScrypt) are slow so you can calculate less rounds in the same time, what weakens the hash. In every case the server must calculate a hash as well to be safe.
The advantage is small, because if an attacker can do a ManInTheMiddle attack, he can also modify/remove the script (JS) which does the hashing. Only an encrypted connection with SSL/HTTPS can protect against a MITM attack, so you need SSL anyway.
In your case with an app, it looks slightly different. Because the user first has to install your software, there is no need to send a script to the client, so a MITM cannot modify this script. Moreover, the app can calculate the hash relatively fast (if it can run native code) and therefore can do enough rounds on client-side.
This is what i would do:
For easiness send the password plain-text over an encrypted SSL/HTTPS connection and calculate the slow BCrypt hash server side, as you do now.
Only if the load on the server grows too heavy, then you can move the calculation of the slow BCrypt hash to the client app. Still use HTTPS to send the hash, and then calculate an additional fast hash (e.g. SHA-256) on the server. This is more complex, because you have to exchange and store the salt separately.
Another disadvantage of hashing passwords on the client is that you cannot change the hashing algorithm or iteration count without also having to update your clients.
For JavaScript clients that is not a problem, but you cannot easily guarantee that your users will be on the most recent version of your native client.
So I would stick with sending plain passwords over HTTPS.
In the early days of HTTP, there was Digest authorization as an alternative to Basic authorization. Instead of the HTTP header
Authorization: Basic <credentials>
you would use
Authorization: Digest <credentials>
It was an algorithm that increased security by avoiding the password being sent as cleartext. This was in the days when TLS/SSL came at a performance cost so this was an alternative. However the algorithm meant the password had to be stored as cleartext on the server. So you had a choice of sending the password cleartext but having a hash on the server, or sending the password as a hash but having cleartext on the server.
Unsurprisingly, as martinstoeckli said in his answer, now that TLS/SSL is widespread and easy to implement, HTTPS is used instead. You can store the password as a hash on the server but not expose the plaintext password if it is intercepted by a MITM attacker.
I need to read data from XLS files that are marked as protected workbooks (of which I have the password). I cannot find any PHP libraries that allows for this functionality, so am looking into writing the code to do so myself. I can't seem to find any information on how the protection is applied, going by this, it is not clear whether any encryption is applied in the case of a protected workbook (selecting protect workbook in the Excel menu). If any encryption is applied, how do you determine which method is applied? The following options are listed:
Weak Encryption (XOR)
Office 97/2000 Compatible
RC4, Microsoft Base Cryptographic Provider v1.0
RC4, Microsoft Base DSS and Diffie-Hellman Cryptographic Provider
RC4, Microsoft DH SChannel Cryptographic Provider
RC4, Microsoft Enhanced Cryptographic Provider v1.0
RC4, Microsoft Enhanced DSS and Diffie-Hellman Cryptographic Provider
RC4, Microsoft Enhanced RSA and AES Cryptographic Provider (Prototype)
RC4, Microsoft RSA SChannel Cryptographic Provider
RC4, Microsoft Strong Cryptographic Provider
When parsing the file with PHP, it does seem like some encryption is applied, as I get jibberish tokens after the FILEPASS (0x2f) token is read. (In this case I just ignored the FILEPASS token)
Are there any libraries that can read data of a protected workbook? (preferably PHP). Any sources which explain how the encryption is done?
I have several independent PHP applications running on few servers. None of the servers have SSL, but I'm able to use PHP wraper for SSL. I would like to ensure all data sent between servers is safe and signed. Do I need to generate an certificate or is it enough to create public/private key everytime I send something? Is this aproach safe?
Do I need to generate an certificate or is it enough to create
public/private key everytime I send something?
Don't generate a public/private key every time. How would you be able to check who has control over the private key? The point of certificates is to be able to bind an identity to a public key: checking you trust the certificate and that you're willing to communicate with the identity it refers to is a necessary component to secure the communication.
From what I understand, the communication between the servers doesn't involve user interaction itself. If you control all the servers, you could give them certificates, either self-signed X.509 certificates (if you can install them all for all parties: only applicable for small numbers in practice) or your own CA (if you have OpenSSL, look into CA.pl, which has a man-page).
You could then sign an encrypt the content you exchange using S/MIME (there are functions available in PHP for this).
(You might also be able to achieve the same goal using PGP, using PGP keys/certificates instead.)
If both machines have mcrypt then you could probably encrypt the text you want to send over the wire in PHP at one end and decrypt it at the other, but of course the big issue you have here is going to be key distribution. You'd either have to pre-configure each machine with the correct key and hope nobody notices you're using the same key every time (which is bad), or you'll have to come up with some kind of way of distributing your key to the receiving machine when you send data without the key being snooped. (which is complicated).
You also mentioned signing, which is also a tricky issue.
Whilst it would in theory be possible to implement all this in PHP using an appropriate extension such as mcrypt, I honestly doubt it would be worth the effort of doing it right, which would be considerable, You'd also just be reinventing the wheel.
SSL implements all the stuff you need already and is the accepted industry standard, if at all possible I'd strongly recommend you install it.
In a little project of mine I use Blowfish encryption for some data transfer, using the mcrypt extension that's available on most servers:
$encrypted = mcrypt_encrypt(MCRYPT_BLOWFISH, 'here goes a key', $data, MCRYPT_MODE_ECB, null);
Decrypting goes the same way, just use mcrypt_decrypt. This is a shared key, not a public/private key system.
i have client-server application (objective-c and php).
how can i encrypt data on client and then decrypt on server?
the simpler the better
The simplest way to encrypt data traveling over the network is going to be to simply always use TLS to connect to your server running your PHP app. You could verify a particular certificate from within your app if you're afraid of sophisticated man in the middle attacks, though that will make your app fail to work without an update when your certificate changes.
If you truly need encryption/decryption at the application level, not just transport, then you should probably use RSA public-key encryption. Your client will have the public key, your server will have the private key. Apple has documentation on RSA encryption.
Okay, rule number 1: DO NOT write your own cryptographic routines.
Given that, there are some standard cryptographic libraries available. OpenSSL is recommended in this SO article.
Use SSL/TLS protocol, OpenSLL have the implementation of both, check this tutorial, its in c but may be a good start to you.
This is for an iPhone app which needs to send encrypted data to a web page running php. Symmetric or asymmetric encryption is fine. Example code would be greatly appreciated.
Using SSL would be your best bet.
Look up AquaticPrime on the web if you want sample code, includes PHP and Objective-C. This is a package based on SSL for license key generation.
PHP has the Mcrypt library available to be installed which has a number of algorithms. Find a similar library with support which is callable from Objective-C, and give them a try. To avoid having a key on with the program, asymmetric or public key would be more secure (otherwise, it's just giving the password away).
http://www.php.net/manual/en/function.mcrypt-decrypt.php
You can encrypt it on your iPhone app and then decrypt it in PHP. You can pick an algorithm which is supported by both platforms (possibly AES). For the key, you could do something like concatenating the user's password and a long string (salt), the string being hard coded into the iPhone app and the PHP app.
That way, an attacker couldn't decrypt the messages without knowing the user's password, and both the PHP and iPhone app would know this password.