I have a need to encrypt and decrypt files using php. I need to have other users a preshared key to be able to decrypt the file. The encryption should be at the lease AES 128. Are there any good articles or tutorials on that
thanks
There are multiple libraries, but the most common is probably mcrypt. A quick Google brings up a host of mcrypt tutorials, eg
http://www.itnewb.com/v/PHP-Encryption-Decryption-Using-the-MCrypt-Library-libmcrypt
Depending on the application I sometimes use http://phpseclib.sourceforge.net/ because it is pure PHP (runs on every PHP server without needing any extensions).
It is not at all clear what your goal is. Essential parts of the problem are:
Key sharing. How do you securely get the key to the user?
Encryption. How do you ensure the security of the key when encrypting the data?
Problem. You need to clearly state what problem that you expect encryption to solve.
Hopefully this will help you form new questions.
Related
In a typical web scenario, a website user will come along, use a website, fill out a form, and transmit the data to the server for storage in the database. Now let's say we needed to ensure their address was encrypted as it was top secret, and only those with access to the back end of the website should be able to see what that address was - this is reasonably easy to achieve right? We would just store an encryption key server-side which would be used to generate the encrypted data, store the data in the DB, and we would just use the key again to decrypt it.
Now supposing someone at the hosting company were to browse the files on your server - they could very easily get access to this encryption key, and then use it to decrypt any data they wanted, since all addresses in the database have been encrypted with the same key!
I am just trying to cover every base with the new security model, and in a "trust no one" policy I am looking at ways of stopping the hosting company from getting at the data too.
So does anyone have any suggestions to prevent those with server access from obtaining the key and decrypting data? Would password salting help in any way, or would they still be able to decrypt data quite easily.
I can't think of a way around the issue. Does anyone have any suggestions to solve this particular problem?
Encrypt and decrypt in the browser everything sent to the host. Use a passphrase entered on the client to do the cryptography, and never send the passphrase to the host. There's a fuller description at Host-proof Hosting
I guess that's a risk when it comes to shared hostings. I'm using amazon aws for most of my projects and linode for my personal blog. Both solutions are in the model "you are your own sysadmin" and nobody peeks in your machines.
If I was in your shoes, I'd use mcrypt with a variable key. For example, whe username field of the same row. This way, for the data to be compromised, the intruder would need to get access to both your database and source code to figure out how to decrypt the data. At that point your problem would be far worse than a mere information leak.
Well mostly hosting companies have access to all databases and files that is bad really bad.
Few years ago I did some experimenting with encryption and decryption.
The best way would be to have personal servers, but that isn't cheap.
Example RC4 encryption requires key to crypt data. Now tricky part is to make that key also encrypted with some other encryption like BASE 64 , ATOM 128. This wont make it be 100% secure
But It will be really hard to decrypt data.
I hope you can understand me.
Cheers :)
btw point is there is no 100% secure data.
If you don't need to be able to decrypt the data online, this is an ideal situation for public-key cryptography. In particular, a sealing API. For example, using libsodium (PHP 7.2):
Encryption
$store_me = sodium_crypto_box_seal($plaintext, $box_publickey);
sodium_memzero($plaintext);
Decryption
$plaintext = sodium_crypto_box_seal_open($stored_msg, $box_keypair);
If, however, you do need to be able to decrypt the data from the webserver, then anyone who accesses the webserver can just pilfer the keys and decrypt your data. No cryptography algorithm can stop someone with the keys from decrypting messages.
Always start with a threat model.
I would like to know if there is a Javascript counterpart to the PHP oppenssl_encrypt and openssl_decrypt functions.
I have developed a unique combination of PHP and AJAX where a user can log in to a website using their username and password and be authenticated without the username or password even being transmitted to the server. The point is, both the server and the user have a never-transmitted secret key that can be used as an encryption key.
I mention this because many of the "answers" I have found here are arguments about why anyone needs to do this, because "any secret key that you use will have to be transmitted". Not the case here, so please don't comment if you are a naysayer.
What I am really looking for is two sets of string encryption/decryption functions that are compatible between PHP and Javascript, using a secret key. Any thoughts?
Ok.. I don't know about openssl_... things, but you can download a js to encrypt / decrypt things with blowfish algorithm. Blowfish is in php too (mcrypt contains this algorithm by defualt).
I googled and found a link
http://dren.ch/js_blowfish/
You can always google things, you may find the same for openssl too!!
Check out the first comment on openssl_decrypt() for the PHP bit, and then you can get the Gibberish Javascript bit here.
I'm working on my first secure shopping site. We're not storing credit card data, so that's not a problem. However, we do have a transaction key and API login key for our payment gateway (authorize.net) that I'd prefer to keep in a database, rather than hard-coding into my php. I don't know that we need tremendous security, but I would rather not store it in plain text. I know about sha, but that's one-way. I need a way to store the value in the database in a semi-secure format, but then be able to "decrypt" it programmatically for use in my function.
An additional caveat to this is that my site is hosted, which means there's a very tight limit to what kind of stuff I can install, so ideally any solution would rely on something that's included with a standard php install.
Can anyone point me in the right direction? I'm very new to securing data.
EDITED TO ADD: I checked with my host and mcrypt is installed. Is this the right direction to look in?
MCrypt can be your friend here. What you do need to take into account, though, is that every publicly available (and useful) encryption method requires a key. If AES encryption or 3DES encryption didn't require a key during the encryption process then breaking the encryption would just be a matter of trying every standard decryption method until you got a meaningful result. Thus, storing the key for your payment gateway incurs the exact same risks as storing the key for your encryption. No matter how many layers of encryption you want to add, at some level there will have to be a key stored in plain text, usually hard-coded into the PHP and often in an included config.php file to make it easy to change in the future.
The only option for securely storing information without the need for a key would be to invent your own encryption method. The security of this method lies solely in the fact that no one knows the means by which you are encrypting the string, so they don't have a step-by-step pattern to just walk backwards through. If you ever told someone how your encryption worked, though, then the security would be forfeit. Also, there are many algorithmic ways to break simple encryptions (letter replacement, for example). This is why mathematicians get a lot of money for developing things like AES.
Your best best is to look into MCrypt Encrypt and MCrypt Decrypt. This way if just your PHP is compromised then they know the key you used to encrypt, but they don't have the data. If just the database is compromised then they have the data but not the key you used to encrypt it. If both are compromised, you're screwed. But if both are compromised you're screwed no matter what you do, so that's a fairly safe route.
Hmm, you can try AES encryption. The problem is that you have to save the salt hash(98sdfx9c6v5c) somewhere in your PHP.
Insert config:
INSERT INTO config (secret_key) VALUES (AES_ENCRYPT('secret api key','98sdfx9c6v5c'));
select config:
SELECT AES_DECRYPT(secret_key,'98sdfx9c6v5c') AS secret_url FROM config
From a security perspective, there's no difference by storing it in the php files or in the database, if someone has access to your php files he has access to the database as well.
working with mcrypt doesn't mean you will have MORE security, (if they can read your php files they can read the key as well) so...
If I were you i'd store the API key in plain text on a file outside the web server directory.
just write good code you should be fine.
I am not sure if this is the right place but lets see.
I am developing an system to send private messages from one user to an other use. Under the hood runs PHP 5.2.x .
Now I am looking for any way to encrypt private messages in a way that i cant access them. At the moment I have no idea how to realize such a system, where I don't know the encryption key.
My first idea was to combine it with something like OAuth.
Some more requirements to clarify the problem:
Public Webpage
good usability
it will never work if you're doing the decryption on your server. You need to do the decryption completely on client side with javascript.
Ideas for looking for information on javascript crypto engines:
http://www.ohdave.com/rsa/
http://www.movable-type.co.uk/scripts/aes.html
If your users all use modern browsers with support for client side database storegae, you can use this to store the keys: an example
you should know, that it would be not very secure if you want the de-/en-cryption to be fast, or it will be really slow, because javascript is not the best language to do crypto stuff.
what about RSA and other public-key cryptography? http://en.wikipedia.org/wiki/Public-key_cryptography
You could use the Diffie-Hellman protocol to generate encryption keys that are only known to the users.
But as a user, you have to have access to those keys in order to read your messages. So you'd have to find a way to store the key at the client instead of your server, otherwise you'd still be able to decrypt the messages. This would be quite a challenge for a PHP site, so I doubt it can be accomplished.
How about you just don't store the key?
I am interested in having something that I encrypt using a public key on a LAMPhp server, decrypted using the appropriate private key on the web client (firefox at least, best if it is standard javascript)
Note that what I want to do is -not- merely to have an encrypted connection using SSL/https. Or even to use browser-based client certificates as a login/access control method. I know how to do both of those things. What I want to do is more like emailing with gpg keys. I want to be able to create a short message that I will encrypt with a users public key that -only they- can decrypt using their private key. What I am looking for is not the privacy achieved automatically by ssl, but the ability to allow only particular users to decrypt messages. I know I can easily do this with gpg or perhaps SMIME, and perhaps that is the best way, but I would prefer a web-based alternative.
Firefox etc have a certificate stores, and I know that the private keys held there are unlikely to be exportable into javascript for obvious security reasons, but I would assume there is some way to -use- the certificates from javascript calls to decrypt something..
The reason I would like to do this, is that I need a secure method to give a randomly generated password to a particluar administrator. I am trying to implement full database translucency and public key cryptography seems like an important part of that effort. But this is one use-case that I am having trouble addressing without this kind of ability.
So on the php side I would use the openssl encryption calls like so...
<?php
$browsers_public_key = get_it_from_the_browser_via_apache_maybe();
openssl_public_encrypt($data,$encrypted_ends_up_here,$browsers_public_key);
echo "<html><head>
<script type='javascript'>
function decrypt_textarea(){
??
}
</script>
</head>
<body><textarea id='decrypt_me'> $encrypted_ends_up_here </textarea>
<div id='where_the_plaintext_goes'> </div>
</body> </html>";
?>
Note that I have found via stackedoverflow many fine javascript encrypton libraries... but I actually want to use keys imported into Firefox as per MyOpenId.com or CaCert.org
Does anyone know if this is possible?
Thanks,
-FT
It's been a while since you asked this question, but if you or anyone else is looking for a potential solution to this problem or a similar one, they should check out the JavaScript Forge project:
http://github.com/digitalbazaar/forge/blob/master/README
This project has an SSL implementation in JavaScript that will allow you to include a client-side certificate when communicating with Apache. You can also manually do RSA decryption using the associated private key (which you have access to in JavaScript).
For instance, the JavaScript could get/post to the server and include its client-side certificate. Apache could read this certificate, use the public key to encrypt whatever data is appropriate, and then return that data to the client. The client could then use its private key (in JavaScript) and decrypt the information and do something with it. This extra encryption is probably not even be necessary, however, if your server can authenticate the client-side certificate as the appropriate recipient of the secret you're trying to pass.
The Forge project also has the APIs to build a system for importing/exporting keys and certificates to/from Firefox or other browsers (if this is still a requirement for some reason). A little help from openssl might be necessary to get the keys/certs in the correct format for import/export (pem => pkcs12), but an example of how some of this works can be found in a JavaScript-based demonstration of WebID. WebID is a client-side certificate-based authentication system:
WebID management demo: https://webid.digitalbazaar.com/manage/
WebID authentication demo: https://payswarm.com/webid-demo/
Note that the SSL certificates for the above sites are self-signed and will require temporary exceptions to be added to your browser to view them. The sites do not require you to enter any personal information, they are for demonstration purposes only. However, if you go to the first link, you can generate keys in-browser (it uses Forge JavaScript to do this) and then you can see the private key and certificate that were generated, in PEM format, in the list at the top of the page. The key and certificate are persisted via Flash local storage.
Nearly 100% (if not that) of the source for the WebID management site is viewable since it is mostly JavaScript. Also, the Forge project itself (see the github link) is opensource.
Now that I understand what you're saying, I can give you a firm answer :)
The best I can tell you is that you can't get decent encryption in the way you're looking to do it. Private key encryption (namely RSA) uses very, very, very large numbers to do encryption. Using small numbers is very simple to crack computationally (there are only so many prime numbers) and the numbers get big extraordinarily quickly. Basically, with RSA, you need to take large numbers and raise them to large exponents. JavaScript is able to support quite large numbers, but you'll hit a wall with performance. With a 512-bit key, encryption of a few kilobytes can take up to a few seconds, while decryption can take seconds to minutes to do. The reason JS is so slow is simply because it's not a compiled language. Sure, you could decrease the key size, but anything larger than a couple kilobytes and you've got a problem.
Also, RSA is inherently insecure in a web page because the private key is transmitted alongside the data to be decrypted (unless it was transferred earlier), which enables anyone that receives the page to decrypt the data.
I'm going to assume that you're looking to do this because you want to obfuscate some code from your user or a client, so I'm going to recommend that you check out XOR encryption. Granted, it's nowhere near as secure as RSA, but it uses principles that can be very secure if used properly. For instance, if you use a random key that's used only once and has the same length as your data/code (an one-time pad), your encryption is "uncrackable". Even better, XOR encryption is FAST. Here are some resources:
http://guymal.com/mycode/xor_js_encryption/
http://javascript.internet.com/passwords/xor-encryption4.html
Hope you have luck with what you're trying to do!
I am searching exactly the same thing you do and wanted to use php's openssl-functions, too.
I was happy to see that on the phpside everything was working great with private/public key (encrypt/decrypt) and now wanted to find a way to use privatekey on clientside as you do.
!!!
IF you will find anything please let me know by email:
pki (at) life.de
!!!
And for the performance aspect:
You would encrypt the big parts with symetric encryption and only the decryption key with the public key of the client to excahnge it. So you dont't need to enrypt many kb.
But it seems to be an dead end with firefox, but with IE and ActiveX it seems possible with
CAPICOM (I had not much read about it now).
hxxp://geekswithblogs.net/shahed/archive/2007/05/03/112232.aspx
But for JavaScript/PHP have a look at (and read all comments at FAQ and other pages,too!In future maybe bidirectional communication was mentioned):
hxxp://www.jcryption.org/
hxxp://www.zend.com//code/codex.php?ozid=1323&single=1
Pure Javascript Public/Privatekey encryption
hxxp://shop-js.sourceforge.net/crypto2.htm
A helful FireFox-Addon for PKI:
hxxps://addons.mozilla.org/en-US/firefox/addon/4471
hxxp://www.mozilla.org/projects/security/pki/nss/tools/index.html
PHP with OpenSSL on Serverside / .NET on CLientside
hxxp://www.csharpbydesign.com/2008/04/asymmetric-key-encryption-with.html
Javascript OpenPGP
hxxp://www.hanewin.net/encrypt/
PS: stupid mechanism prevents me posting links ...
You don't handle SSL in your PHP. SSL is handled by the web server automatically. If you're using Apache, here's a simple tutorial:
http://www.debian-administration.org/article/Setting_up_an_SSL_server_with_Apache2
The idea is that you write your code like normal, and when the user accesses your site using https, the server automatically encrypts the connection. On the client side, the browser is capable of using the private keys that it already has to automagically decrypt the connection and present the code to the user agent.
Hope this helps!