PHP class or method to decrypt the DES Encryption - php

Are DES Encryption called "One Way Encryption" or "two way Encryption" ?
Are there a PHP class or method to decrypt the DES Encryption ?

The php crypt function is a one-way hashing function, if you want to be able to decrypt, take a look at the mcrypt extension which supports a range of algorithms

It should be noted that there are (and have always been) questions surrounding the DES algorithm. It's been widely in use for a long time, but since it was originally specified with only a 56 bit key, it's questionable whether it's secure enough for any important uses at this point. Triple DES is generally better, but there are some known theoretical attacks. If you have a choice of cipher, you might want to look at AES instead.

DES can be reversed, so it's a two-way encryption (if you meant that).
DES is a pretty well known encryption standard so it should be available in PHP too.

One-way encryption is a secure form of hashing: the plaintext is changed into an apparently random sequence of data, often of fixed length, in such a way that the original plaintext (theoretically) cannot be retrieved without a brute-force effort.
Two-way encryption, or reversible encryption is what we normally mean by the term encryption: the plaintext is transformed into apparently random data, but in a way that relies on a "key" that allows the original plaintext to be retrieved.
DES is a form of reversible encryption that is relatively weak by today's standards, as it relies on a 56-bit key (14 hex characters). It has been superseded by 3DES, or triple-DES, which is essentially the same algorithm with a longer key.
You don't mention your application, but if you need only to compare the data and not retrieve it, hashing is considered more secure. For example, you can store hashed passwords; then, when a user authenticates, perform the same hash on the entered text and compare it with the stored hashed value. If they match, the correct password was entered.
A significant advantage to hashing is that you don't need to store a decryption key.

I am not familiar with the "one way encryption" or "two way encryption" terms. There is a term "one time password" (totally irrelevant for DES), and there are "symmetric" and "assymetric" encryption algorithms, meaning whether the same key is used for encryption and decryption (symmetric) or a set of two different keys is used one for encryption and another for decryption (assymetric). DES is a symmetric algorithm. As for PHP, crypt() since to be doing the job:
http://us2.php.net/crypt

I Think you probably mean a one-way function [1]. In cryptography one distinguishes between symmetric and asymmetric cryptography. Symmetric cryptography uses the same key to encrypt and decrypt (DES is symmetric). Asymmetric Cryptography is used for key exchange and a public key is used to encrypt the message, while the private key is used to decrypt it. An example of Asymmetric Cryptography is AES [2]. Asymmetric cryptography uses one way functions.
[1] http://en.wikipedia.org/wiki/One-way_function
[2] http://en.wikipedia.org/wiki/AES

Related

Why does PHP crypt function use DES encryption algorithm?

Given that the rule of thumb is to store salted hashes of the password string, not the encrypted form of it, why does the PHP crypt() function use the DES-based algorithms? Isn't DES an encryption algorithm? The manual says
... crypt() will return a hashed string using the standard Unix DES-based algorithm or alternative algorithms that may be available on the system ...
What I understand from here is that crypt() only uses the algorithm as implemented by the system. And surely DES is implemented as an encryption algorithm rather than a custom hashing algorithm for crypt.
PS - I know that DES was way back in the past and nobody should use it anymore.
The idea of DES-based password hashing is, basically, to encrypt a block of zeroes with the password and passed salt for some number of rounds. Any half-decent encryption makes key recovery hard even in the face of known plaintext, so that’s why it’s possible to make strong password hashes out of encryption functions.
I think the PHP default is compatible with this scheme.

Is there a hashing method which is 'dehashable'?

I know that hashing functions such as SHA1 and MD5 are one-way encryption systems.
But is there a hashing method which is 'dehashable'?
Like, it produces an x-character string, which can then be 'dehashed' into the original string.
Is there such a hashing method? It will be appreciated if it was PHP compatible.
UPDATE: What I mean by a hashing function is an encryption method which produces an x-character string, which can be decrypted. Sorry for the confusion.
hashing functions such as SHA1 and MD5 are one-way encryption systems.
Not quite - they are as you say hashing functions. They are often used together with encryption systems, e.g. for password hashing algorithms, but they are not encryption systems or encryption algorithms.
But is there a hashing method which is 'dehashable'?
No, it would not be a hash function then, since a hash function maps a larger data set to a smaller data set. This has the side effect that you can get the same hash value out of different input data, which makes calculating the original data from the hash key impossible. What it does allow is, for instance, to check if the original data has been modified - you apply the same hash function to the original data again and compare the calculated hash keys. If they are different, the original data was modified - if they are the same, the original data is (at least very very likely) unmodified.
What you are looking for is probably either a compression/decompression algorithm or an encryption/decryption algorithm.
Hashing is not (one-way) encryption, as a hash value can never be decrypted to the original value; this is by design.
Also, hash functions are designed to make it very hard to come up with a data set the will match a given hash value (cf. collision)
As Andreas suggests, you are looking for compression or crypto functions.

Switching from md5() to crypt()

So far I have been using md5 to hash passwords on my site, no salt.
Now I am building an application that will have to be more secure and I'm reading md5 can be easily brute-force attacked.
So I want to use crypt() to hash the passwords.
What I have not fully understood is:
Do I have to provide a salt or is the built-in generated one ok?
How many times (if more than one) should I iterate the crypt function to be safe?
With md5, no matter the length of the input string, the hash was 32-digit. Does crypt return a standard length of hashes too?
You need to provide a salt, if you want to specify encryption other than DES. Otherwise, you're good with the default salt.
You don't iterate the crypt function yourself, this is done internally with algorithms where it makes sense. Number of iterations is specified via the salt.
Yes, the hash length of a given hash algorithm is standard; different hash algorithms have different hash lengths, however.
crypt can use different hash algorytms. With md5 it returns 128 bit integer (with 32 chars hex representation). Using crypt with a salt once is safe enought. It's recommended the salt to be provided by the application
An optional salt string to base the hashing on. If not provided, the
behaviour is defined by the algorithm implementation and can lead to
unexpected results.

Good cryptographic hash functions [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Secure hash and salt for PHP passwords
I am making a website, and I need a secure algorithm to store passwords.
I was first thinking of bcrypt, but then I found out my host did not support it and I am not able to change host.
My host allow this encryption:
Standard DES
And these hashes:
MD5
md2, md4 & md5
sha1, sha256, sha384 & sha512
ripemd128, ripemd160, ripemd256 and ripemd360
whirlpool
tiger128,3, tiger160,3, tiger192,3, tiger128,4, tiger160,4 & tiger192,4
snefru
gost
adler32
crc32 & crc32b
haval128,3, haval160,3, haval192,3, haval224,3, haval256,3, haval128,4, haval160,4, haval192,4, haval224,3, haval256,4, haval128,5, haval160,5, haval192,5, haval224,5 & haval256,5
So, can anyone of you fix a good algorithm with that and a salt, please?
You shouldn't store encrypted (or even unencryped) passwords at all. Instead, use salted hashes (stretched, e.g. with PBKDF2), preferably SHA2-512.
For reference, here is a classification of the listed hashes (See wikipedia for details):
Encryption (not a hash function): DES
Non-cryptographic checksums (laughable): adler32, crc32, crc32b
Broken: MD2, MD4, MD5,SHA1
Probably broken: Tiger, snefru, GOST, HAVAL*
Probably safe: SHA2-256/384/512, RIPEMD-128/256, RIPEMD-160/320, WHIRLPOOL
Note that the strength refers to the attack of finding any password that matches a known hash (preimage attack). Also, the above sorting is paranoid, instantly discarding any hash with any known vulnerabilities.
crc32, adler32 etc. are not designed to be cryptographically secure -- they're merely fast checksum algorithms. I think salted SHA-256 should offer a good combination of security and compatibility.
On a somewhat less serious note, I once recall using salted MD5 on a slow server that was expected to tank moderate load. So I decided to pad it with a 32-bit random salt, and stored the whole thing as hexadecimal -- it gave off the impression the whole thing was unsalted SHA-1. I sincerely hope someone wasted precious time running rainbow tables on the stolen dump!
Security isn't really all about more expensive hashing :)
You should
Use a salt as part of your hash.
Use an iterative routine in the 10,000+ iteration range. For example, PBKDF#2.
Use a known strong hash (SHA-256, SHA-512)
You should store passwords as hashes as mentioned above, not encrypted.
A hash function is basically a one way transformation which always produces the same hash for the same input argument. It should not be possible to transform the hash back to its original form, or the hash function is to be considered broken.
An encryption is a two way transformation where you can transform the encrypted data back into its original form if you have the key.
By storing passwords as hashes, and as they are one way transformed, they can not be extracted even if someone were to get hold of the database.
When checking a password simply transform it with the same hash function you used on your stored password and check against the database.
As gnur said, you need to decide if you want to hash or encrypt passwords. If these are passwords for your own users and the passwords are only being used on your system, then hash them using salt and stretching. Of the hash algorithms you have available use SHA-256 or SHA-512. For salt use 128 random bits (16 bytes). Ideally use a cryptographic RNG though a non-crypto RNG will do in a pinch. The attacker is assumed to know the salts anyway. Stretch enough that it takes about 0.1 second to process a single password. This limits any attacker to ten attempts at breaking a password every second.
If you are storing passwords to log on to an external system then you will need to encrypt the passwords and decrypt them when needed. DES is your only real option here, unless you also have 3DES (aka Triple DES or DESede) available. I am surprised that AES/Rijndael is not available. If it is then us it in preference to DES.

Encryption: Use of initialization vector vs key?

I am using PHP's mcrypt library and the AES-256 (rijndael) algorithm, which requires both a key + initialization vector to run.
My logical brainside isn't really going along with this. Isn't just one key enough?
Theoretical scenario:
If I had encrypted sensitive data stored in a database, which only the owner should be able to decrypt, would it be appropriate to use the users hashed password to either the key or the initialization vector to his or her data?
Should the key be considered more private than the initialization vector or is it the other way around?
No, in fact an IV is vital in most implementations. The IV is also considered to be safe for public use, for instance the IV is transmitted in plain text for WEP and WPA1/WPA2. The problem arises when this same key+iv is used to encrypt the same plain text. The cipher texts will be identical, unless you use an IV. If an attacker can encrypt arbitrary plain text with this key, and then view the cipher text. This is a much faster way of brute forcing other cipher text that the attacker has obtained.
Not only that, the IV must be random or you would be in violation of CWE-329. The reason why this is a problem is a bit more subtle and I didn't get it at first. You didn't mention this, but i hope you are using either the CBC or CMAC modes
The use of a hash function on a password is nearly identical to using a String2Key function. This is a solid design so long as an attacker can't use SQL Injection to obtain the key.
Initialization Vector (IV) is not a key at all, and is not secret. In fact, it is often exposed (e.g. prepended to the encrypted data). It is used as an additional random input to the encryption algorithm so that the result of encrypting the same clear data is different each time you use a different IV. This way, statistics cannot be gathered on the encrypted data. It does not "improve" the encryption strength by itself.
You can look here for nice diagrams showing how and why IV is used.
Do not use hashed password as a single source for key and IV. As a rule of thumb, you should generate random IV EVERY TIME you update encrypted data and store IV with this data. Key can be reused multiple times, but use salted hashing and store salt with data too.
If you just hash user passwords and use it as encryption keys, users with same passwords will have same keys. Depending on your database structure and intruder access rights there could be some unfortunate cases when users with same passwords can be detected. Add at least unique username to this hash.
If you do not change IV for every data update, information about data changes can be leaked. With CBC or CFB mode identical first plaintext blocks will be encrypted to identical ciphertext until first plaintext change, so position of this change can be determined.
If you're using the EBP mode of the block cipher, or most of the stream ciphers, identical key+IV combinations on different plaintexts will offer the attackers a direct view on the XOR result of the key. This by extension reveals the key itself and to some extent the password.
But do I mean IVs are definitely necessary? No. As long as you change your password each and every time on your next plaintext block(even the same block the second time), you're completely fine without IVs. In fact, all that an IV does is the automation of the above process.

Categories