PHP - Using a Unix Timestamp as a key? - php

So, I've been looking into encryption lately, and I've heard of people using timestamps as keys for encryption. I think this is a great idea, but if I want to decrypt the data, how would I retrieve that specific timestamp? Timestamps are unique, and I'm not really sure how this would work.
EDIT:
I am using PHP and MYSQL

Er, usually timestamps are used as the basis for generating keys - not as the key itself. The key is something you have to store for later if you want to be able to decrypt the data.

Two problems here.
You would need to store the timestamp somewhere. So why not just use "rand()" and store that.
Its possible to get hundreds of duplicate timestamps on a modern multi-threaded, multi-core processor. So you may as well just use date().

The only way would be to save the timestamp. (assuming there is no backdoor to your encryption, which would nullify it's purpose)
What I would do is save the timestamp along with the encrypted string in a different format Ex: 09/21/2011 03:09:53 and use a combination of strtotime() and salting to store both bits of information in a secure manor.
09/21/2011 03:09:53 becomes 13165--Salt--74593

Timestamps make awful keys. A program could blaze through all possible keys in the blink of an eye.
The time is often used a component is priming a random number generator. It can't be the only component for the same reason it can't be used as a key, though.
The time could be used semi-successfully as the salt for a hashing algorithm. It's still not as good as something random since it allows the attacker to generate rainbow tables in advance.

I don't want to hurt your feelings, but...
It is very obvious that you have never studied crypto.
So, please do not design your own cryptographic protocols, and do not assemble cryptographic primitives yourself either (like the "WiFi" designers/amateurs cryptologists did with WEP).
Protocols designed to meet specific security goals (I am not saying "secure protocols" on purpose) have been invented and implemented by specialists.
You first need to define your security goals, then choose an adequate protocol.

Related

Hiding true database object ID in url's

What would be useful solutions for hiding true database object ID in URL for security purposes? I found that one of the solutions would be:
1) Using hashids open source project
2) Using something like same old md5 on creation of the object to generate hash and store it in database, then use it in url's and querying by them, but the drawback is that querying by auto-incremented primary keys (IDs) is faster than hashes. So I believe the possibility to hash/unhash would be better?
Also as I'm on Symfony, are there maybe bundles that I could not find or built in functionalities that would help?
Please tell me what you found useful based on your experiences.
This question has been asked a lot, with different word choice (which makes it difficult to say, "Just search for it!"). This fact prompted a blog post titled, The Comprehensive Guide to URL Parameter Encryption in PHP .
What People Want To Do Here
What People Should Do Instead
Explanation
Typically, people want short random-looking URLs. This doesn't allow you much room to encrypt then authenticate the database record ID you wish to obfuscate. Doing so would require a minimum URL length of 32 bytes (for HMAC-SHA256), which is 44 characters when encoded in base64.
A simpler strategy is to generate a random string (see random_compat for a PHP5 implementation of random_bytes() and random_int() for generating these strings) and reference that column instead.
Also, hashids are broken by simple cryptanalysis. Their conclusion states:
The attack I have described is significantly better than a brute force attack, so from a cryptographic stand point the algorithm is considered to be broken, it is quite easy to recover the salt; making it possible for an attacker to run the encoding in either direction and invalidates property 2 for an ideal hash function.
Don't rely on it.
Quote from the site:
Do you have a question or comment that involves "security" and "hashids" in the same sentence? Don't use Hashids.
I'd use true encryption algorithm, like function openssl_encrypt (for example), or something like this. And encrypt ids when passing outside, decrypt when using in your code (like for db queries).
And I won't recommend storing ids in a base like any kind of encrypted "garbage", in my opinion its very inconvenient to hash your real ids. Keep it clean and pretty inside and encrypt for external display only.
Following your idea, you just need to cipher your IDs before writing the URL to HTML page and decipher them when processing those URLs.
If you want just security by obscurity, which is sufficient for, maybe 99% of curious people out there who likes to iterate over IDs in URLs, you use something simple like base64 or rot13. Of course, you can also precalculate those "public IDs" and store in the database, not encrypting each time the URL is being shown to end user.
If you want true security you have to encrypt them with some serious asymmetric cypher, storing both keys at your side, as you essentially talking with yourself and don't want a man-in-the-middle attack. This you will not be able to precalculate as at each encrypting there'll be different cyphertext, which is good for this cause.
In any case, you need something two-way, so if I were you I'd forget about word "hash", hashes are for purposes different from yours.
EDIT:
But the solution which every blog out there uses for this task for several years already is just to utilize URL rewriting, converting, in your case, URLs like http://example.com/book/5 to URLs like http://example.com/rework-by-37signals. This will completely eradicate any sign of database ID from your URL.
Ideologically, you will need something which will uniquely map the request URL to your database content anyway. If you hide MySQL database IDs behind any layer of URL rewriting, you'll just make this rewritten URL a new ID for the same content. All you gain is protection from enumeration attacks and maybe SEF URLs.

URL Parameters - Encoding [duplicate]

What would be useful solutions for hiding true database object ID in URL for security purposes? I found that one of the solutions would be:
1) Using hashids open source project
2) Using something like same old md5 on creation of the object to generate hash and store it in database, then use it in url's and querying by them, but the drawback is that querying by auto-incremented primary keys (IDs) is faster than hashes. So I believe the possibility to hash/unhash would be better?
Also as I'm on Symfony, are there maybe bundles that I could not find or built in functionalities that would help?
Please tell me what you found useful based on your experiences.
This question has been asked a lot, with different word choice (which makes it difficult to say, "Just search for it!"). This fact prompted a blog post titled, The Comprehensive Guide to URL Parameter Encryption in PHP .
What People Want To Do Here
What People Should Do Instead
Explanation
Typically, people want short random-looking URLs. This doesn't allow you much room to encrypt then authenticate the database record ID you wish to obfuscate. Doing so would require a minimum URL length of 32 bytes (for HMAC-SHA256), which is 44 characters when encoded in base64.
A simpler strategy is to generate a random string (see random_compat for a PHP5 implementation of random_bytes() and random_int() for generating these strings) and reference that column instead.
Also, hashids are broken by simple cryptanalysis. Their conclusion states:
The attack I have described is significantly better than a brute force attack, so from a cryptographic stand point the algorithm is considered to be broken, it is quite easy to recover the salt; making it possible for an attacker to run the encoding in either direction and invalidates property 2 for an ideal hash function.
Don't rely on it.
Quote from the site:
Do you have a question or comment that involves "security" and "hashids" in the same sentence? Don't use Hashids.
I'd use true encryption algorithm, like function openssl_encrypt (for example), or something like this. And encrypt ids when passing outside, decrypt when using in your code (like for db queries).
And I won't recommend storing ids in a base like any kind of encrypted "garbage", in my opinion its very inconvenient to hash your real ids. Keep it clean and pretty inside and encrypt for external display only.
Following your idea, you just need to cipher your IDs before writing the URL to HTML page and decipher them when processing those URLs.
If you want just security by obscurity, which is sufficient for, maybe 99% of curious people out there who likes to iterate over IDs in URLs, you use something simple like base64 or rot13. Of course, you can also precalculate those "public IDs" and store in the database, not encrypting each time the URL is being shown to end user.
If you want true security you have to encrypt them with some serious asymmetric cypher, storing both keys at your side, as you essentially talking with yourself and don't want a man-in-the-middle attack. This you will not be able to precalculate as at each encrypting there'll be different cyphertext, which is good for this cause.
In any case, you need something two-way, so if I were you I'd forget about word "hash", hashes are for purposes different from yours.
EDIT:
But the solution which every blog out there uses for this task for several years already is just to utilize URL rewriting, converting, in your case, URLs like http://example.com/book/5 to URLs like http://example.com/rework-by-37signals. This will completely eradicate any sign of database ID from your URL.
Ideologically, you will need something which will uniquely map the request URL to your database content anyway. If you hide MySQL database IDs behind any layer of URL rewriting, you'll just make this rewritten URL a new ID for the same content. All you gain is protection from enumeration attacks and maybe SEF URLs.

Store an API response as a hash for comparing against subsequent queries

I'm querying an API for a set of data which may change in the future, however I only want to process the response if there is a change.
What I figured would be a workable solution but am yet to find anything to support my way of thinking, is to pass the response into a hash and record that result into a table, then when doing subsequent queries I can generate and compare the hash before processing the data received.
The data returned can be considerable in size and may have the slightest change (just a single character) and I'm wanting to be certain that it will be reflected in the resulting hash. I'm also concerned about the speed of generating the hash supplying such a large dataset, I believe md4 would be the fastest.
What do I need to consider? or is proposed method above sufficient?
The fastest algorithm in PHP that I'm aware of for spot-checking would be CRC32
<?php
$test = crc32("generated-output-goes-here");
?>
It may be advisable to run this on 64-bit platforms exclusively (without requiring tweaks). This is because on 32-bit systems, the PHP integers are signed and some will return negative.

Comparable hashes

i wasn't able to answer my question.
I need a hashing method that will generate a hash that can be compared with others and find out the fidelity,
let's say i have to 2 strings, "mother", "father" and when i compare the 2 hashes, it will say that there is a fidelity between them because of the "ther".
Is there any hashing method that it's able to do that?
thank you
PHP provides a function called similar_text which calculates similarity between two strings. You could also use the levenshtein function to calculate the distance between the two strings. Whilst these aren't hashing functions, I think they should provide the functionality I think you're after.
I'm not sure if you were looking for an answer specific to your specific case of 2 words, but there are definitely hash-style functions that are useful for comparing parts of a whole. A Hash Tree is a perfect example of one such structure. Hash trees are used to compare parts of a chunk of data and they aggregate for comparison of the entire chunk of data.
I'll also note that while others point out that most real world hash functions will not allow any information about the input to be derived from the output, they are talking about a Cryptographic Hash Function. The set of guarantees for a regular Hash Function is much less strict than those of a Cryptographic Hash Function. For instance, in Java you can override .hashCode() and return 4 for every object. This is perfectly valid, but not extremely useful. It is valid because collisions are ok in general hash functions, but they are considered failure in a cryptographic hash function.
I believe rot13, along with taking out all the vowels would qualify. Any real-world hash would not. That's kind of the point.
In short: There can't be in a universal sense of the word
This is why:
One of the main functions of a hash is compression - apart from trivial usage (such as "mother" and "father") a hash will allways be shorter than the hashed information. E.g. a SHA1 (or even MD5) as a quick check, whether a a download of a 600MB ISO went without corruption will be much shorter than the file itself.
Another main function of a hash is (very high grade) obfuscation. Were this not so, hashing a salted password would do nothing (or at least much less) to protect against a dicitionary attack, as similar passwords would result in similar hashes.

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).

Categories