Crypt script PHP - php

I have my own crypt/decrypt function in PHP which is on my server.
I feel it is not a safe thing to store it in my server as if one day we get to be hacked. The hacker can decrypt easily our datas.
Would like to know if is there is solution to this ? How can we protect our own PHP functions ? Is it better to store the decrypt function in another server.
Thank you in advance for your answers !

It looks like you want to disregard Kerckhoffs's principle and that is fine in some cases. If you want to encrypt data at rest, then there is essentially nothing you can do besides obfuscation (PHP code "encryption" techniques are nothing more than clever (?) obfuscation).
For example: Since every obfuscation can be reversed with enough time (but not so much time what would needed to break an encryption), a key that was used to encrypt the data and which is embedded in the code can be extracted and your data decrypted.
If the server only stores encrypted data (which I somehow doubt because that would make it not very useful) and never uses the decryption, only then it would add some security to your arrangement by out sourcing the decryption function. This would raise the bar, because the attacker would need to exploit (possibly other) weaknesses of the second server.

Do Not Implement Your Own Crypto
Never try to develop your own crypto. You should choose use one of tested and trusted by professional. Please watch this video I believe you will understand why you shouldn't implement your own crypto. ( https://www.youtube.com/watch?v=3Re5xlEjC8w#t=49 )
If you really want yo use your own crypto, you may want to encode your php application. Because likely to you are going to store your private key into your source codes.
Example for Plain-text form of PHP source code.
It will be something like when you encode your this php source code.
Further information : http://www.virtual-apps.com/post/security-and-performance-benefits-of-encoding-php-files

Related

Encrypting mssql queries

I have a weird question,
Is it possible to encrypt mssql sp or triggers or even queries? like in php base64 system.
If it's possible, can someone provide me a link of the method or a small tutorial explaining how to use the encrypted method to be read from sql?!
all I want is a small encryption method that allows me to encrypt my queries and let the sql read it over the encryption itself. just like php
If I understand correctly you want encryption to happen in SQL itself. I would suggest against this as it kind of defeats the whole purpose of encrypting the data. The reason behind it is usually that if a 3rd party gains access to your database (and not application code), they still cannot read the data. If you set encryption to happen in SQL, then they will be able to decrypt the data.
If this is not what you've wanted, then sorry for my wasted reply.

How to implement 2 way encryption with either PHP or mySQL?

I am trying to securely store OAuth tokens and keys, and I know best practice is to encrypt these and treat them like user passwords. How can I do that while still being able to decrypt them and use them to make API calls to, say, twitter (I simply hash my passwords, which won't work for OAuth keys, as hashing is 1 way)?
I am open to doing it either in mySQL or PHP, so I would appreciate examples in either, or pros/cons of each approach.
You could use the mcrypt library in PHP (http://php.net/manual/en/book.mcrypt.php), it has support for all major cryptographic algorithms. I suggest you use AES-128, this is kind of the industry standard. Just make sure you store your key in a secure location. You can then encrypt your data, convert it to base64 and store that in your database. Whenever you need to use the data, just retrieve it from the database and apply the inverse operations.
I'm not familiar with how MySQL works exactly. Maybe there is a possibility to store data encrypted and have it store your key somewhere secure for you?
From a security point of view, the PHP method would be better though, because data going to and coming from your database is still encrypted.
Please don't use the XOR cypher, it is laughable at best. A single leaked plain-ciphertext pair will reveal your complete key (plaintext XOR ciphertext = key). This only provides perfect security when used as a one-time pad. Of course you can't use this, because now you have to use a different key for every piece of data and somehow have to securely store all those one-time pads. Maybe you could use some encryption for that ;) ...? (insert infinite loop here).

2-way encryption in PHP - need some guidance

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.

How to encode/encrypt secret data to be transferred by URL parameters?

Here's the story:
I have to pass some classified information from one script to another script. In the first script I need to encrypt the data first and then I have to attach the encrypted data into a GET request and send it to another script. The URL would look like this:
http://mydomain.com/mysecondscript.php?secret={encrypted stuff}
My current encrypt method is based on base64. The problem with this method is, that if I have a lot of stuff to encrypt, the encrypted result could get very long. If it's longer than 255 characters or so, the second script will not be able to decrypt it because the string will be chopped.
So I'm looking for a better encryption method, that can control the length of the encrypted result.
DANGER!
Base64 is NOT a form of encryption, but encoding. Base64 encoded strings are easy to recognize and trivial to decode. Base64 is used to encode data so they can be safely transmitted across non-binary safe medium (such as URLs and emails), but they do not hide the data itself.
What you need to do is encrypt the string using AES (see PHP's mcrypt), then base64 encode it. This of course will not solve your length problem. The question is pretty vague, but what you can do is:
Use POST instead of GET.
Store data in a database or a file which both scripts can access. Then just generate a sort of identifier and send it with the URL. The receiving script can use this identifier to retrieve the data. As an added bonus you won't have to send classified data with the URL.
EDIT: Now that I read your question more carefully, it seems like both scripts are sitting on the same server. In this case there is no reason whatsoever to pass this data via HTTP.
No matter how secure your encryption scheme is you will still need to base64 or URL-encode the result which, you have discovered, will likely exceed 255 characters. The best you can do is compress the data, then encrypt it, then encode it. It will still probably fail. You need to find an alternative to GET.
Why does it have to be transmitted in the URL at all? Save it to disk, put it in the database, add it to a message passing queue...
You can use an opaque token in the URL to identify which thing you're talking about, and then turn that token back into a useful thing on the other end by querying whatever storage mechanism you choose.
If this is sensitive information, base64 should not be used as it can be decoded easily. If you want the information to be securely encrypted, you shoule use PHP Mcrypt (link). Much more secure and can support encryption of much longer strings. Best of all, you set your own key and it cannot be decrypted without that key. It make require a tiny bit more work, but it will be safe. Also, if you are passing multiple variables that way, you can set them into an array, serialize and encrypt the array, pass the array via GET, and then decrypt/unserialize. It's as simple as that. One last thing, there are also some classes out there that will make Mcrypt a lot easier to use. May want to google to find one, it will make your life easier.
You can use MD5 to create a hash of the id so you get something like:
http://www.demo.com/displaycommittees.php?id=81dc9bdb52d04dc20036dbd8313ed055
In your db query you can do a select on the users table including a WHERE statement that also hashes the id column like:
WHERE MD5(id) = $_GET[id]
This works fine and i have always applied this algorithm. for instance assuming the actual value of the encrypted id 23, if you try to put 23 in place of the encrypted(hash) code it will not work( no result will be display).
Note: Reasons are best known to those who need a solution, so the question "why" may not come in for those who need it. they only ask for a solution and if it works fine for them, nice. But for transaction application (e.g cash transaction or transaction pins) please do avoid passing sensitive information via URL, because it can easily be cracked.
See more at: http://softideass.blogspot.com/

get firefox to decrypt using private portion of client certificate

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!

Categories