I saw a 'confirm_code' column in a db table, and property of the column is varchar(100),
can you guys give me idea of a nice algo for a confirmation code ? Basically, it should consist of a random characters. The simplest things in my mind is just encrypting a string through md5 or sha1 but it won't fit because of the current column property.
An md5 hash should easily fit in a varchar(100)... in hex form an MD5 hash is typically 32 characters long.
You can generate unique ID's with uniqid().
Related
I asked a question here and I manage to partially implement the advice. Data is now stored encrypted in binary field (varbinary(500)), after I remove the aes-256 encryption and I leave aes-128 (default) codeigniter encryption.
However, I have some questions, and I can't find answers, since I can not find many articles on this subject, so If anyone can answer my questions, or point me to a book, or any other literature for further reading, I would be very grateful.
Why encrypted data must be stored in binary type field? What is wrong with storing it in longtext, or varchar? Does that make the encryption worthless?
Why I must first encode the variable and then encrypt it when I store the data in the binary type of field, and I don't have to do that when I store the data in varchar field?
base64_encode($clientName);
$encClientName = $this->encryption->encrypt($clientName);
In my previous question (see the link on the top) I have been advised to use nonce. Since I didn't know how to use that with codeigniter library, I didn't implement that part. Does that make my data less secure? Can anyone post any snippet code of how to use nonce with the codeigniter?
Again, any link to reading material on this subject (storing encrypted data in the database with php) will be deeply appreciated.
Why encrypted data must be stored in binary type field? What is wrong with storing it in longtext, or varchar? Does that make the encryption worthless?
Encrypted data is binary. It will frequently contain byte sequences which are invalid in your text encoding, making them impossible to insert into a column which expects a string (like VARCHAR or TEXT).
The data type you probably want is either VARBINARY (which is similar to VARCHAR, but not a string) or BLOB (likewise, but for TEXT -- there's also MEDIUMBLOB, LONGBLOB, etc).
Why I must first encode the variable and then encrypt it when I store the data in the binary type of field, and I don't have to do that when I store the data in varchar field?
You don't. This is backwards.
If you were going to use a string-type column to store encrypted data, you could "fake it" by Base64 encoding the data after encryption. However, you're still better off using a binary-type column, at which point you don't need any additional encoding.
In my previous question (see the link on the top) I have been advised to use nonce. Since I didn't know how to use that with codeigniter library, I didn't implement that part. Does that make my data less secure?
Based on what I'm seeing in the documentation, I think the CodeIgniter Encryption library handles this for you by default. You shouldn't have to do anything additional.
In addition to duskwuffs answer, I covered your questions from a more crypto-related viewpoint. He just managed to post a minute before I did :)
Encrypted data must be stored in a binary type field due to the way that Character Encodings work. I recommend you read, if you haven't already, this excellent article by Joel Spolsky that details this very well.
It is important to remember that encryption algorithms operate on raw binary data. That is, a bit string. Literal 1's and 0's that can be interpreted in many ways. You can represent this data as unsigned byte values (255, 255), Hex (0xFF, 0xFF), whatever, they are really just bit strings underneath. Another property of encryption algorithms (or good ones, at least) is that the result of encryption should be indistinguishable from random data. That is, given an encrypted file and a blob of CSPRNG generated random data that have the same length, you should not be able to determine which is which.
Now lets presume you wanted to store this data in a field that expects UTF8 strings. Because the bit string we store in this field could contain any possible sequence of bytes, as we discussed above, we can't assume that the sequence of bytes that we store will denote actual valid UTF8 characters. The implication of this is that binary data encoded to UTF8 and then decoded back to binary is not guaranteed to give you the original binary data. In fact, it rarely will.
Your second question is also somewhat to do with encodings, but the encoding here is base64. Base64 is a encoding that plays very nicely with (in fact, it was designed for) binary data. Base64 is a way to represent binary data using common characters (a-z, A-Z, 0-9 and +, /) in most implementations. I am willing to bet that the encrypt function you are using either uses base64_decode or one of the functions it calls does. What you should actually be interested in is whether or not the output of the encrypt function is a base64 string or actual binary data, as this will affect the type of data field you use in your database (e.g. binary vs varchar).
I believe in your last question you stated that you were using CTR, so the following applies to the nonce used by CTR only.
CTR works by encrypting a counter value, and then xor-ing this encrypted counter value with your data. This counter value is made up of two things, the nonce, and the actual value of the counter, which normally starts at 0. Technically, your nonce can be any length, but I believe a common value is 12 bytes. Because the we are discussing AES, the total size of the counter value should be 16 bytes. That is, 12 bytes of nonce and 4 bytes of counter.
This is the important part. Every encryption operation should:
Generate a new 12 byte nonce to use for that operation.
Your implementation should add the counter and perform the actual encryption.
Once you have the final ciphertext, prepend the nonce to this ciphertext so that the result is len(ciphertext) + 12) bytes long.
Then store this final result in your database.
Repeating a nonce, using a static nonce, or performing more than 2^32 encryption operations with a single 12 byte nonce will make your ciphertext vulnerable.
I'm trying to use mcrypt_create_iv to generate random salts. When I test to see if the salt is generated by echo'ing it out, it checks out but it isn't the required length which I pass as a parameter to it (32), instead its less than that.
When I store it in my database table however, it shows up as something like this K??5P?M???4?o???"?0??
I'm sure it's something to do with the database, but I tried to change the collation of it to correspond with the config settings of CI, which is utf8_general_ci, but it doesn't solve the problem, instead it generates a much smaller salt.
Does anyone know of what may be wrong? Thanks for any feedback/help
The function mcrypt_create_iv() will return a binary string, containing \0 and other unreadable characters. Depending on how you want to use the salts, you first have to encode those byte strings, to an accepted alphabet. It is also possible to store binary strings in the database, but of course you will have a problem to display them.
Since salts are normally used for password storing, i would recommend to have a look at PHP's function password_hash(), it will generate a salt automatically and includes it in the resulting hash-value, so you don't need a separate database field for the salt.
How can I Decode the md5, crc32, and sha1, below is xml file and then is code I'm using to get data so far.
<files>
<file name="AtTheInn-Germany-Morrow78Collection.mp3" source="original">
<format>VBR MP3</format>
<title>At the Inn - Germany - Morrow 78 collection</title>
<md5>056bbd63961450d9684ca54b35caed45</md5>
<creator>Germany</creator>
<album>Morrow 78 collection</album>
<mtime>1256879264</mtime>
<size>2165481</size>
<crc32>22bab6a</crc32>
<sha1>796fccc9b9dd9732612ee626c615050fd5d7483c</sha1>
<length>179.59</length>
</file>
And this is code I'm using to get title and album name how can I make sense of sha1 and md5, any help to any direction will be helpful, Thanks
<?php
$search = $_GET['sku'];
$catalogfile = $_GET['file'];
$directory = "feeds/";
$xmlfile = $directory . $catalogfile;
$xml = simplexml_load_file($xmlfile);
list($product) = $xml->xpath("//file[crc32 = '$search']");
echo "<head>";
echo "<title>$product->title</title>";
MD5, SHA-1, and CRC32 are hash functions. That means that they cannot be reversed.1 You'd have more luck looking into that name attribute of the file tag.
1 You can2 brute-force them, but since they can represent variable-length data as a fixed-length piece of data, due to the pigeonhole principle and just plain probability, you're more likely to get something that's not the original input than the original input.
2 It'll take forever for SHA-1, though.
Hash functions generate numbers that represent some arbitrary data. They can be used to verify if the data has changed (a good hash function should produce a totally different hash for even a single bit has changed).
Since you are turning an arbitrary amount of data in a number as a result you loose information, this means that it's hard to reverse them. Technically there is an infinite number of possible results for a hash as the data can be any length. For limited data sizes its still possible for there to be multiple data values for a specific hash, this is called a collision.
For some data sets (for example passwords) you can generate all possible combinations of data and check to see if they match a hash. If you do the generation at the same time as the checking it's known as 'brute forcing'. You can also store all possible combinations (for a limited range, for example all dictionary works or all combinations of characters under a specific size), then look it up. This is known as a rainbow table and is useful for reversing multiple hashes.
It's good practice to store passwords as a hash rather than in plain text but to ensure the passwords are hard to reverse they add a bit of random data to each one and store it along with the passwords, this is known as salting. This salt means it takes much longer to brute force a password.
In this case they are probably hashes of the mp3 file that is specified to verify file integrity and show any corruption that occurs during transfer (or storage). It won't be possible to reverse them since you would have to generate all possible combinations of megabytes of data. But if you have the file itself there wouldn't be any reason too. You can confirm they are hashes of the file by running a checksum generating program on it.
I am working on a php/mysql login system for a webproject. After looking through SO and alot of articles on the web Ive come up with a basic framework and started writing some code for it. However Ive come to a bit of an impasse in password encryption.
After a nights worth of reading Ive found out that:
I should the users password with at least sha1 or sha2
I should also use a randomly generated salt (this is what I need help with) and append it to the password before encrypting it
the hashed password and the randomly generated salt should be stored in the database and then queried and combined/encrypted then checked against the users hashed password.
My problem is coming in randomly generating the salt,
Possibilities I can think of:
Use mt_rand() in a loop to pick an ASCII code, get the corresponding character with chr() and concatenate to salt.
This allows to create salts with any length.
Define a string with available characters, use mt_rand() in a loop to pick random positions from it, extract the character in the selected position with substr() or mb_substr() and concatenate to salt.
This allows to create salts with a chosen character set and length.
Use a builtin function that generates a random string (e.g. uniqid()) and optionally hash it.
This is quick and simple.
I normally use the second option.
uniqid() ?
http://sg2.php.net/uniqid
I was wondering if I use PHP's hash() function to generate sha512 hashes how would my MySQL table field look like in-order to be capable of holding the hashed password.
Here is my current MySQL password field layout
char(40)
A sha512 hash is represented as a 128 characters-long string.
For example, the following portion of code :
$sha512 = hash('sha512', "Hello, World!");
echo strlen($sha512);
Will give this output :
128
Which means your char(40) is far too small, and that you should use a char(128).
Another solution would be to store it in a binary form, and not a string -- which would mean 64 bytes.
But note it might be harder to deal with that representation, in some cases, I suppose.