8. februar 2011

Understanding Hash Functions and Keeping Passwords Safe

Understanding Hash Functions and Keeping Passwords Safe:

From time to time, servers and databases are stolen or compromised. With this in mind, it is important to ensure that some crucial user data, such as passwords, can not be recovered. Today, we are going to learn the basics behind hashing and what it takes to protect passwords in your web applications.


1. Disclaimer

Cryptology is a sufficiently complicated subject, and I am by no means an expert. There is constant research happening in this area, in many universities and security agencies.

In this article, I will try to keep things as simple as possible, while presenting to you a reasonably secure method of storing passwords in a web application.


2. What Does “Hashing” Do?

Hashing converts a piece of data (either small or large), into a relatively short piece of data such as a string or an integer.

This is accomplished by using a one-way hash function. “One-way” means that it is very difficult (or practically impossible) to reverse it.

A common example of a hash function is md5(), which is quite popular in many different languages and systems.

$data = 'Hello World';
$hash = md5($data);
echo $hash; // b10a8db164e0754105b7a99be72e3fe5

With md5(), the result will always be a 32 character long string. But, it contains only hexadecimal characters; technically it can also be represented as a 128-bit (16 byte) integer. You may md5() much longer strings and data, and you will still end up with a hash of this length. This fact alone might give you a hint as to why this is considered a “one-way” function.



3. Using a Hash Function for Storing Passwords

The usual process during a user registration:

  • User fills out registration form, including the password field.

  • The web script stores all of the information into a database.

  • However, the password is run through a hash function, before being stored.

  • The original version of the password has not been stored anywhere, so it is technically discarded.

And the login process:

  • User enters username (or e-mail) and password.

  • The script runs the password through the same hashing function.

  • The script finds the user record from the database, and reads the stored hashed password.

  • Both of these values are compared, and the access is granted if they match.

Once we decide on a decent method for hashing the password, we are going to implement this process later in this article.

Note that the original password has never been stored anywhere. If the database is stolen, the user logins can not be compromised, right? Well, the answer is “it depends.” Let’s look at some potential problems.




4. Problem #1: Hash Collision


A hash “collision” occurs when two different data inputs generate the same resulting hash. The likelihood of this happening depends on which function you use.


How can this be exploited?


As an example, I have seen some older scripts which used crc32() to hash passwords. This function generates a 32-bit integer as the result. This means there are only 2^32 (i.e. 4,294,967,296) possible outcomes.


Let’s hash a password:



echo crc32('supersecretpassword');
// outputs: 323322056

Now, let’s assume the role of a person who has stolen a database, and has the hash value. We may not be able to convert 323322056 into ‘supersecretpassword’, however, we can figure out another password that will convert to the same hash value, with a simple script:



set_time_limit(0);
$i = 0;
while (true) {

if (crc32(base64_encode($i)) == 323322056) {
echo base64_encode($i);
exit;
}

$i++;
}

This may run for a while, though, eventually, it should return a string. We can use this returned string — instead of ‘supersecretpassword’ — and it will allow us to successfully login into that person’s account.


For example, after running this exact script for a few moments on my computer, I was given ‘MTIxMjY5MTAwNg==‘. Let’s test it out:



echo crc32('supersecretpassword');
// outputs: 323322056

echo crc32('MTIxMjY5MTAwNg==');
// outputs: 323322056

How can this be prevented?


Nowadays, a powerful home PC can be used to run a hash function almost a billion times per second. So we need a hash function that has a very big range.


For example, md5() might be suitable, as it generates 128-bit hashes. This translates into 340,282,366,920,938,463,463,374,607,431,768,211,456 possible outcomes. It is impossible to run through so many iterations to find collisions. However some people have still found ways to do this (see here).


Sha1


Sha1() is a better alternative, and it generates an even longer 160-bit hash value.




5. Problem #2: Rainbow Tables


Even if we fix the collision issue, we’re still not safe yet.



A rainbow table is built by calculating the hash values of commonly used words and their combinations.




These tables can have as many as millions or even billions of rows.


For example, you can go through a dictionary, and generate hash values for every word. You can also start combining words together, and generate hashes for those too. That is not all; you can even start adding digits before/after/between words, and store them in the table as well.


Considering how cheap storage is nowadays, gigantic Rainbow Tables can be produced and used.


How can this be exploited?


Let’s imagine that a large database is stolen, along with 10 million password hashes. It is fairly easy to search the rainbow table for each of them. Not all of them will be found, certainly, but, nonetheless…some of them will!


How can this be prevented?


We can try adding a “salt”. Here is an example:



$password = 'easypassword';

// this may be found in a rainbow table
// because the password contains 2 common words
echo sha1($password); // 6c94d3b42518febd4ad747801d50a8972022f956

// use bunch of random characters, and it can be longer than this
$salt = 'f#@V)Hu^%Hgfds';

// this will NOT be found in any pre-built rainbow table
echo sha1($salt . $password); // cd56a16759623378628c0d9336af69b74d9d71a5

What we basically do is concatenate the “salt” string with the passwords before hashing them. The resulting string obviously will not be on any pre-built rainbow table. But, we’re still not safe just yet!




6. Problem #3: Rainbow Tables (again)


Remember that a Rainbow Table may be created from scratch, after the database has been stolen.


How can this be exploited?


Even if a salt was used, this may have been stolen along with the database. All they have to do is generate a new Rainbow Table from scratch, but this time they concatenate the salt to every word that they are putting in the table.


For example, in a generic Rainbow Table, “easypassword” may exist. But in this new Rainbow Table, they have “f#@V)Hu^%Hgfdseasypassword” as well. When they run all of the 10 million stolen salted hashes against this table, they will again be able to find some matches.


How can this be prevented?


We can use a “unique salt” instead, which changes for each user.


A candidate for this kind of salt is the user’s id value from the database:



$hash = sha1($user_id . $password);

This is assuming that a user’s id number never changes, which is typically the case.


We may also generate a random string for each user and use that as the unique salt. But we would need to ensure that we store that in the user record somewhere.



// generates a 22 character long random string
function unique_salt() {

return substr(sha1(mt_rand()),0,22);
}

$unique_salt = unique_salt();

$hash = sha1($unique_salt . $password);

// and save the $unique_salt with the user record
// ...

This method protects us against Rainbow Tables, because now every single password has been salted with a different value. The attacker would have to generate 10 million separate Rainbow Tables, which would be completely impractical.




7. Problem #4: Hash Speed


Most hashing functions have been designed with speed in mind, because they are often used to calculate checksum values for large data sets and files, to check for data integrity.


How can this be exploited?


As I mentioned before, a modern PC with powerful GPU’s (yes, video cards) can be programmed to calculate roughly a billion hashes per second. This way, they can use a brute force attack to try every single possible password.


You may think that requiring a minimum 8 character long password might keep it safe from a brute force attack, but let’s determine if that is, indeed, the case:



  • If the password can contain lowercase, uppercase letters and number, that is 62 (26+26+10) possible characters.

  • An 8 character long string has 62^8 possible versions. That is a little over 218 trillion.

  • At a rate of 1 billion hashes per second, that can be solved in about 60 hours.


And for 6 character long passwords, which is also quite common, it would take under 1 minute.


Feel free to require 9 or 10 character long passwords, however you might start annoying some of your users.


How can this be prevented?


Use a slower hash function.



Imagine that you use a hash function that can only run 1 million times per second on the same hardware, instead of 1 billion times per second. It would then take the attacker 1000 times longer to brute force a hash. 60 hours would turn into nearly 7 years!



One way to do that would be to implement it yourself:



function myhash($password, $unique_salt) {

$salt = "f#@V)Hu^%Hgfds";
$hash = sha1($unique_salt . $password);

// make it take 1000 times longer
for ($i = 0; $i < 1000; $i++) {
$hash = sha1($hash);
}

return $hash;
}

Or you may use an algorithm that supports a 'cost parameter,' such as BLOWFISH. In PHP, this can be done using the crypt() function.



function myhash($password, $unique_salt) {

// the salt for blowfish should be 22 characters long

return crypt($password, '$2a$10.$unique_salt);

}

The second parameter to the crypt() function contains some values separated by the dollar sign ($).


The first value is '$2a', which indicates that we will be using the BLOWFISH algorithm.


The second value, '$10' in this case, is the "cost parameter". This is the base-2 logarithm of how many iterations it will run (10 => 2^10 = 1024 iterations.) This number can range between 04 and 31.


Let's run an example:



function myhash($password, $unique_salt) {
return crypt($password, '$2a$10.$unique_salt);

}
function unique_salt() {
return substr(sha1(mt_rand()),0,22);
}

$password = 'verysecret';

echo myhash($password, unique_salt());
// result: $2a$10$dfda807d832b094184faeu1elwhtR2Xhtuvs3R9J1nfRGBCudCCzC

The resulting hash contains the algorithm ($2a), the cost parameter ($10), and the 22 character salt that was used. The rest of it is the calculated hash. Let's run a test:



// assume this was pulled from the database
$hash = '$2a$10$dfda807d832b094184faeu1elwhtR2Xhtuvs3R9J1nfRGBCudCCzC';

// assume this is the password the user entered to log back in
$password = 'verysecret';

if (check_password($hash, $password)) {
echo 'Access Granted!';
} else {
echo 'Access Denied!';
}

function check_password($hash, $password) {

// first 29 characters include algorithm, cost and salt
// let's call it $full_salt
$full_salt = substr($hash, 0, 29);

// run the hash function on $password
$new_hash = crypt($password, $full_salt);

// returns true or false
return ($hash == $new_hash);
}

When we run this, we see 'Access Granted!'




8. Putting it Together


With all of the above in mind, let's write a utility class based on what we learned so far:



class PassHash {

// blowfish
private static $algo = '$2a';

// cost parameter
private static $cost = '$10';

// mainly for internal use
public static function unique_salt() {
return substr(sha1(mt_rand()),0,22);
}

// this will be used to generate a hash
public static function hash($password) {

return crypt($password,
self::$algo .
self::$cost .
' . self::unique_salt());

}

// this will be used to compare a password against a hash
public static function check_password($hash, $password) {

$full_salt = substr($hash, 0, 29);

$new_hash = crypt($password, $full_salt);

return ($hash == $new_hash);

}

}

Here is the usage during user registration:



// include the class
require ('PassHash.php');

// read all form input from $_POST
// ...

// do your regular form validation stuff
// ...

// hash the password
$pass_hash = PassHash::hash($_POST['password']);

// store all user info in the DB, excluding $_POST['password']
// store $pass_hash instead
// ...

And here is the usage during a user login process:



// include the class
require ('PassHash.php');

// read all form input from $_POST
// ...

// fetch the user record based on $_POST['username'] or similar
// ...

// check the password the user tried to login with
if (PassHash::check_password($user['pass_hash'], $_POST['password']) {
// grant access
// ...
} else {
// deny access
// ...
}



9. A Note on Blowfish Availability


The Blowfish algorithm may not be implemented in all systems, even though it is quite popular by now. You may check your system with this code:



if (CRYPT_BLOWFISH == 1) {
echo 'Yes';
} else {
echo 'No';
}

However, as of PHP 5.3, you do not need to worry; PHP ships with this implementation built in.




Conclusion


This method of hashing passwords should be solid enough for most web applications. That said, don't forget: you can also require that your members use stronger passwords, by enforcing minimum lengths, mixed characters, digits & special characters.


A question to you, reader: how do you hash your passwords? Can you recommend any improvements over this implementation?



"

Build a Kickbutt CSS-Only 3D Slideshow

Build a Kickbutt CSS-Only 3D Slideshow:

In this tutorial, I’m going to show you how to create a 3D slideshow using only HTML and CSS. No JavaScript required! Fire up Safari and let’s get started!


Theory

Before we dive into building our slideshow, it’s important to understand our approach. We’ll be using the new 3D transforms that are part of the CSS3 specification. You’ve probably seen other tutorials on how to use these transforms to build objects and animate them in a 3D space. Usually when creating a slideshow, we’d rely on JavaScript to trigger those transforms. JavaScript would detect a click event and update one of our HTML elements (typically by adding a class). The updated element would then receive new CSS styles.

What’s different about this tutorial is that we will bypass JavaScript by using only CSS to trigger click events and update our element’s styles. Jeffrey Way’s recent Quick Tip, Mimic a Click Event with CSS, describes a way of doing this using the :target pseudoclass. Here, we’ll use the :focus pseudoclass and the HTML5 element <figcaption>, but the idea is the same.

This method isn’t necessarily “better” than using JavaScript, but simply a neat alternative that takes advantages of the newest HTML5 elements.


Step 0: Getting Started

Let’s start by creating an index.html and style.css. We’ll also create an images folder.

Our 3D object will be a rectangular box with four 940px by 400px faces and two 400px by 400px faces. I’ve included six images in the source files. Place these, or your own versions, in the ‘images’ folder.


Step 1: The HTML

Below is our base HTML. We’ll be wrapping everything with a container and our slideshow, naturally, will be located within a div element called slideshow.


<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>CSS 3D Slideshow</title>
<link rel="stylesheet" type="text/css" href="style.css"/>
</head>

<body>
<div id="container">
<div id="slideshow">
</div>
</div>
</body>
</html>

Within slideshow add the following code for our six images:

<figure id="box">
<img src="images/face1.jpg"/>
<img src="images/face2.jpg"/>
<img src="images/face3.jpg"/>
<img src="images/face4.jpg"/>
<img src="images/face5.jpg"/>
<img src="images/face6.jpg"/>
</figure>

Note that our images (the six faces of our 3D object) are wrapped in a <figure> with the ID of box. This element is what we will rotate when animating our slideshow.

The Trick

Now comes the trick that allows us to use only CSS to detect click events. We will wrap box with six other <figure> elements. Each one will represent a different rotation of our 3D object. The attribute tabindex allows these elements to receive the pseudoclass :focus.

Each <figure> will also need a <figcaption> element inside of it. These captions will serve as our buttons. When clicked they will trigger the parent <figure> to receive :focus. That will allow us to use six different CSS transforms on box.

It might sound a bit complicated right now, but it’ll make sense once we get to the CSS. For now, just wrap box with six <figure> elements and give each a unique tabindex and ID. Then include a <figcaption> for every <figure>.


Final HTML


The final markup in index.html should look like this:



<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>CSS 3D Slideshow</title>

<link rel="stylesheet" type="text/css" href="style.css"/>

</head>

<body>
<div id="container">
<div id="slideshow">
<figure tabindex=1 id="fig1">
<figcaption>Side 1</figcaption>
<figure tabindex=2 id="fig2">
<figcaption>Side 2</figcaption>
<figure tabindex=3 id="fig3">
<figcaption>Side 3</figcaption>
<figure tabindex=4 id="fig4">
<figcaption>Side 4</figcaption>
<figure tabindex=5 id="fig5">
<figcaption>Side 5</figcaption>
<figure tabindex=6 id="fig6">
<figcaption>Side 6</figcaption>
<figure id="box">
<img src="images/face1.jpg"/>
<img src="images/face2.jpg"/>
<img src="images/face3.jpg"/>
<img src="images/face4.jpg"/>
<img src="images/face5.jpg"/>
<img src="images/face6.jpg"/>
</figure>
</figure>
</figure>
</figure>
</figure>
</figure>
</figure>
</div> <!-- End Slideshow -->
</div> <!-- End Container -->
</body>
</html>



Step 2: Basic CSS


First, let’s open up style.css and paste some reset code in, just for good measure. (Removing any outlines that :focus might cause is important.)



/* RESET */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
:focus {
outline: 0;
}
/* HTML5 tags */
header, section, footer,
aside, nav, article {
display: block;
}

Next, we’ll give our page a nice gradient background:



html {
width: 100%;
height: 100%;
background-color: #FFFFFF;
background-image: -moz-linear-gradient(top, #FFFFFF, #b3b3b3);
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #FFFFFF),color-stop(1, #b3b3b3));
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#FFFFFF', EndColorStr='#b3b3b3');
-ms-filter: 'progid:DXImageTransform.Microsoft.gradient(startColorStr='#FFFFFF', EndColorStr='#b3b3b3')';
}

The background-image code includes the Mozilla and WebKit vender prefixes. In case you want a version of the slideshow to work with Internet Explorer, the filter and -ms-filter will create a gradient in IE6, 7 and 8. (I generated this code on the useful site www.css3please.com.)


Now, let’s add some code for our container, slideshow, and box:



#container {
width: 960px;
margin: 0 auto;
}

#slideshow {
width: 900px;
margin: 50px auto 0 auto;
padding: 50px 0 0 0;
}

figure {
display: inline;
}

#box {
position: relative;
display: block;
width: 900px;
height: 400px;
}

Our container will have a width of 960px and be centered with margin: 0 auto. The slideshow div will be 900px wide, centered, and pushed down 50px from the top of the page. We’re also giving it 50px of padding at the top. This padding area will contain our slideshow buttons, the <figcaption> elements, once we position them.


The element which actually contains our slideshow, box, is set to the same size as our images. It’s also important to set position to relative as we’ll be absolutely positioning some of its children. Our other <figure>s are set to display: inline, but box must be a block element.


Now, set the following styles for our six images:



#box img {
position: absolute;
top: 0;
left: 0;
}

We position our images absolutely so they will all stack directly on top of each other at the top left corner of box. (By default, top and left are set to 0. It’s been included for the sake of clarity.)


Right now, our slideshow looks like this:



Let’s add some styling for our <figcaption> buttons:



figcaption {
display: inline-block;
width: 70px;
height: 35px;
background: rgba(0,0,0,0.6);
border: 1px solid rgba(0,0,0,0.7);
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
text-align: center;
line-height: 35px;
color: #ffffff;
text-shadow: 1px 1px 1px #000000;
cursor: pointer;

position: relative;
top: -50px;
left: 150px;
margin: 0 30px 0 0;

-moz-transition: all 0.1s linear;
-o-transition: all 0.1s linear;
-webkit-transition: all 0.1s linear;
transition: all 0.1s linear;
}

The first section of these styles is purely aesthetic. It makes the buttons semi-transparent and rounded and the text centered and shadowed. It also changes the mouse cursor to a pointer, so that users know they can click.


The second section positions our buttons above the images, centers them, and spaces them out.



Make sure you position the buttons outside the boundaries of the six <figure> elements. Otherwise, clicking on the button will actually register as a click on the innermost <figure> instead of the one corresponding to that button.



The last bit of code adds transitions. That’s because we’re about to add styling to the <figcaptions> hover state:



figcaption:hover {
background: rgba(0,0,0,0.8);
}

Our styled buttons should look like this:





Step 3: The 3D Box


The first thing we need to do is tell the browser we’ll be working in a 3D space. We do this by using the perspective property on a parent element. Let’s apply it (with the WebKit vender prefix) to slideshow:



#slideshow {
width: 900px;
margin: 50px auto 0 auto;
padding: 50px 0 0 0;
-webkit-perspective: 800; /* triggers a 3D space */
}

The value of perspective determines how many pixels the “viewer” is from the 3D object. The lower the value the more exaggerated the 3D effect.



We also need to preserve the 3D space throughout all our child elements. To do this we’ll add the property transform-style: preserve-3d to all our <figures>s. (Again, we’ll be using the WebKit vender prefix.)



figure {
display: inline;
-webkit-transform-style: preserve-3d; /* maintains 3D space */
}

Alright, now it’s time to transform the individual faces (our six images) to build a 3D box. We’ll target each image using the nth-child() pseudoclass, but giving each <img> a specific ID would also work. Make sure you add this code underneath the current styles in the stylesheet.


Here’s the code, I’ll explain it below:



#box img:nth-child(1) {
-webkit-transform: rotateX(0deg) translateZ(200px);
}

#box img:nth-child(2) {
-webkit-transform: rotateX(180deg) translateZ(200px);
}

#box img:nth-child(3) {
-webkit-transform: rotateX(90deg) translateZ(200px);
}

#box img:nth-child(4) {
-webkit-transform: rotateX(-90deg) translateZ(200px);
}

#box img:nth-child(5) {
-webkit-transform: rotateY(-90deg) translateZ(200px);
}

#box img:nth-child(6) {
-webkit-transform: rotateY(90deg) translateZ(700px);
}

Okay, so here is what’s going on: The first image is not rotated at all, but it is translated forward (toward the viewer) 200 pixels on its Z-axis.



The second image is rotated around its X-axis by 180 degrees so that it is facing away from the viewer. It is then pushed away from the viewer 200 pixels on its Z-axis.




Notice that the order of transformations matter — the rotation changes the object’s origin and then the translation occurs along a new axis.


Our third and fourth images are each rotated around the X-axis to face up and down, respectively. Then both are translated 200 pixels along their new Z-axes.




Remember, our box is 900px wide by 400px high by 400px deep. The four sides (the 940px by 400px faces) must be 400 pixels away from each other. That’s why we translate them all 200 pixels in opposite directions. The two ends (the 400px by 400px faces) we will translate 900 pixels away from each other.


The fifth and sixth images are currently on the left side of box and not centered. Because of this, our fifth and sixth images receive different translations. They both have their origin 200 pixels to the right of the left end of box. The fifth image must be rotated -90 degrees around the Y-axis to face left and then translated 200 pixels along its new Z-axis. This places it on the left end of our 3D object. The sixth image is rotated 90 degrees around the Y-axis to face right and then translated 700 pixels along its new Z-axis. This places it on the right end of our 3D object.




The best way to get a sense of what we’ve done is to look at the current arrangement of images. If you preview the slideshow in Safari you’ll currently see this:



Let’s hide the front face — just so we can see if our other images are positioned correctly:



#box img:nth-child(1) {
-webkit-transform: rotateX(0deg) translateZ(200px);
display: none; /* temporarily hide */
}

Now we can see the inside of our box:



Now, remove the display: none from our first image. You might have noticed that the box is bigger on the screen — closer to the viewer — than it should be. The front face especially looks overly large and stretched.


To correct for this we need to move the entire 3D object away from the viewer by 200 pixels. Add -webkit-transform: translateZ(-200px) to the styles for box. While we are at it we should also add the transition property:



#box {
position: relative;
display: block;
width: 900px;
height: 400px;
-webkit-transform: translateZ(-200px); /* Pushes 3D object back into place */
-webkit-transition: -webkit-transform 1s; /* Enables transitions for transforms */
}

With all that set, we are ready to animate our box.




Step 4: Animation


Paste in our final block of styling. This will add our animations. I’ll explain in more detail below.



#fig1:focus #box {
-webkit-transform: translateZ(-200px) rotateY(0deg);
}

#fig2:focus #box {
-webkit-transform: translateZ(-200px) rotateX(-180deg);
}

#fig3:focus #box {
-webkit-transform: translateZ(-200px) rotateX(-90deg);
}

#fig4:focus #box {
-webkit-transform: translateZ(-200px) rotateX(90deg);
}

#fig5:focus #box {
-webkit-transform: translateZ(-450px) rotateY(90deg);
}

#fig6:focus #box {
-webkit-transform: translateZ(-450px) rotateY(-90deg);
}

When each of our <figure> elements receives the pseudoclass :focus we rotate box to display the correct side. Notice that the box rotations are all the opposite of the rotations we used on each individual face. For example, the fourth image was rotated negative 90 degrees around the X-axis. To bring it into view we must rotate the entire 3D object positive 90 degrees around the X-axis. The translations ensure that the side of the 3D object we’re viewing is always the correct distance away.


That’s it! Check out the slideshow in Safari to make sure everything is working.



Final CSS


The final styling in style.css should look like this:



/* RESET */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
:focus {
outline: 0;
}
/* HTML5 tags */
header, section, footer,
aside, nav, article {
display: block;
}

html {
width: 100%;
height: 100%;
background-color: #FFFFFF;
background-image: -moz-linear-gradient(top, #FFFFFF, #b3b3b3);
background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0, #FFFFFF),color-stop(1, #b3b3b3));
filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#FFFFFF', EndColorStr='#b3b3b3');
-ms-filter: 'progid:DXImageTransform.Microsoft.gradient(startColorStr='#FFFFFF', EndColorStr='#b3b3b3')';
}

#container {
width: 960px;
margin: 0 auto;
}

#slideshow {
width: 900px;
margin: 50px auto 0 auto;
padding: 50px 0 0 0;
-webkit-perspective: 800; /* triggers a 3D space */
}

figure {
display: inline;
-webkit-transform-style: preserve-3d; /* maintains 3D space */
}

#box {
position: relative;
display: block;
width: 900px;
height: 400px;
-webkit-transform: translateZ(-200px); /* Pushes 3D object back into place */
-webkit-transition: -webkit-transform 1s; /* Enables transitions for transforms */
}

#box img {
position: absolute;
top: 0;
left: 0;
}

figcaption {
display: inline-block;
width: 70px;
height: 35px;
background: rgba(0,0,0,0.6);
border: 1px solid rgba(0,0,0,0.7);
-moz-border-radius: 20px;
-webkit-border-radius: 20px;
border-radius: 20px;
text-align: center;
line-height: 35px;
color: #ffffff;
text-shadow: 1px 1px 1px #000000;
cursor: pointer;

position: relative;
top: -50px;
left: 150px;
margin: 0 30px 0 0;

-moz-transition: all 0.1s linear;
-o-transition: all 0.1s linear;
-webkit-transition: all 0.1s linear;
transition: all 0.1s linear;
}

figcaption:hover {
background: rgba(0,0,0,0.8);
}

#box img:nth-child(1) {
-webkit-transform: rotateX(0deg) translateZ(200px);
}

#box img:nth-child(2) {
-webkit-transform: rotateX(180deg) translateZ(200px);
}

#box img:nth-child(3) {
-webkit-transform: rotateX(90deg) translateZ(200px);
}

#box img:nth-child(4) {
-webkit-transform: rotateX(-90deg) translateZ(200px);
}

#box img:nth-child(5) {
-webkit-transform: rotateY(-90deg) translateZ(200px);
}

#box img:nth-child(6) {
-webkit-transform: rotateY(90deg) translateZ(700px);
}

#fig1:focus #box {
-webkit-transform: translateZ(-200px) rotateY(0deg);
}

#fig2:focus #box {
-webkit-transform: translateZ(-200px) rotateX(-180deg);
}

#fig3:focus #box {
-webkit-transform: translateZ(-200px) rotateX(-90deg);
}

#fig4:focus #box {
-webkit-transform: translateZ(-200px) rotateX(90deg);
}

#fig5:focus #box {
-webkit-transform: translateZ(-450px) rotateY(90deg);
}

#fig6:focus #box {
-webkit-transform: translateZ(-450px) rotateY(-90deg);
}



Final Thoughts


There is probably no way to justify using a bunch of nested <figure>s and<figcaption> elements as buttons under the current CSS3 recommendations. Nor does this experiment respect the distinction of HTML for content, CSS for style, and JS for behavior. And since these transforms currently only work in Safari, this slideshow is by no means ready to actually be used in client projects. But the purpose of this experiment is to both showcase and push the limits of the new HTML5 and CSS3 features.


If you are interested in adapting this slideshow for browsers with less support, here are some helpful tips:



  • Use Modernizr. Seriously!

  • Only Safari supports the 3D transforms but you could create a nifty slideshow using 2D transforms and support a much wider range of browsers.

  • The opacity property would make a great fading slideshow and work in nearly every browser. (You’d need filter for IE).

  • The <figcaption> buttons will break in Firefox if they are absolutely positioned. It’s weird, I know. Just make sure you use relative positioning.


I hope you guys enjoyed this tutorial. I’m looking forward to your comments and thank you so much for reading!



"

31. januar 2011

Intel's mSATA SSD 310 reviewed: a pint-size performer through and through

Intel's mSATA SSD 310 reviewed: a pint-size performer through and through:

The forecast for speedy, razor-thin laptops is looking pretty sunny right about now, because it seems Intel's SSD 310 truly does bring the power of a full-sized solid state drive on a tiny little board. Storage Review and The SSD Review thoroughly benchmarked the tiny 80GB mSATA module this week, and found it performs even better than advertised -- easily tearing through 200MB / sec reads and 70 MB / sec writes -- which put it slightly behind Intel's legendary X25-M series but well ahead of the company's X25-V boot drives. While we're still not seeing Sandforce speeds from Intel's tried-and-true controller and 34nm silicon and they might not make Toshiba's Blade run for the hills, we can't wait to test it out in some new Lenovo ThinkPads when they integrate the SSD 310 later this year. Oh, by the way, that big green board up above isn't the drive. It's actually the tiny one on top.

Visualized: Google's periodic table of APIs

Visualized: Google's periodic table of APIs:

The world of Google APIs and developer tools can be a confusing one, but the company has now at least brought a bit of order to the chaos with its own take on the periodic table of the elements. As you can see above, Android occupies the top spot normally reserved for hydrogen in the actual periodic table, and the remaining APIs and developer products are all grouped into their appropriate categories -- and, of course, linked to their respective websites. Hit up the link below to check out the table in its interactive form.

Motorola lifts our spirits with new Atrix 4G video

Motorola lifts our spirits with new Atrix 4G video:

Been feeling down this cold and dreary January? Well, let Motorola 'introduce' you to its new smartphone! The CES conqueror we already know as the Atrix 4G has received its first promo video from the mothership, highlighting its laptop and HD multimedia docks (giving us a decent peek at the docked UI for both), dual-core processor and related gaming credentials, and, of course, that gorgeous qHD screen resolution on the handset itself. It's all set to a very uplifting soundtrack, connoting all the beautiful opportunity and potential that our collective smartphone future holds.

13. januar 2011

Motorola Xoom to boast barometer, budding meteorologists have found their next tablet

Motorola Xoom to boast barometer, budding meteorologists have found their next tablet:

To say Motorola's Xoom had a coming-out party at CES would be understating things greatly. It was easily one of the highlights of the show, and the potential that was shown was obviously just part of the story. According to Moto's developer page, there's actually a barometer included, right alongside an accelerometer, magnetometer, ambient light sensor and gyroscope. Oddly enough, a proximity sensor is left out of the mix, but seriously... a barometer? Truth be told, this is actually just an oft overlooked point that was first shown in VZW / Motorola's joint press release, but it's good to know that at least one flagship slate will be compatible with Android 2.3's barometer support. Here's hoping it'll be useful for helping you sidestep ugly weather patterns, or something of the sort.

Bigfoot Networks intros Killer E2100-powered motherboards from ASUS, MSI and Gigabyte

Bigfoot Networks intros Killer E2100-powered motherboards from ASUS, MSI and Gigabyte:

Looks like that tease was more than just a tease. It's a truism. Back at Computex, Bigfoot Networks' CEO told us that his next major target was motherboards. The company already infused its Killer E2100 gaming network card into a GPU, and here at CES, it's formally announcing three partnerships with major mainboard makers. MSI, ASUS and Gigabyte are all onboard, with the latter to offer a new line of G1-Killer mobos later in the year. ASUS will be dishing out a ROG Rampage III Black Edition (shown above) which will feature the E2100 on a combined LAN / audio called dubbed ThunderBolt, but your guess is as good as ours when it comes to specifications and CPU compatibility. Pricing and release information remain a mystery across the range, but it's practically a guarantee that we'll see more of these tie-ups in the coming months.

Gigabyte shows off its new S1080 Windows 7 slate in Taiwan to little fanfare and even less excitement

Gigabyte shows off its new S1080 Windows 7 slate in Taiwan to little fanfare and even less excitement:

So, while all the cool kids were showing off their wares at CES, the good people at Gigabyte decided to throw their own tablet party across the Pacific. The S1080 is the slate you never asked for, in that it runs Windows 7 on a dual core Atom N550 processor underneath a 10.1-inch capacitive touchscreen with 1024 x 600 resolution. If multitouch navigation isn't your thing (an odd preference for those buying tablets), there are a couple of tactile mouse buttons on one edge and an optical mouse on the opposite side for thumbs-only operation. The device has a massive (for a tablet) 320GB hard drive, SD card reader, ethernet port, and USB 3.0 connectivity to sate your computing needs. Also included is a 1.3 megapixel webcam, 802.11b/g/n WiFi, and Bluetooth 3.0. Lastly, in what can only be considered an odd design choice, our Taiwanese friends elected to give the S1080 a VGA port instead of an HDMI connection. Word on the street is that the device will be less than $300 when it goes on sale next month, so if you are a member of the (presumably small) group of people who aren't interested in an Android, Apple, Blackberry, or HP slate, the S1080 may be the tablet for you.

Motorola Atrix: another look (video)

Motorola Atrix: another look (video):

Every CES there's something so alluring that we can't help going back for seconds (or thirds). This year it happens to be the Motorola Atrix, which is undoubtedly our gadget of the show, and which Myriam already put together an in-depth hands-on for. We've been using every excuse we can to swing past Motorola's booth 'on our way' to other stuff on the show floor, and we finally broke down and went in for another hands-on. Check out our video walkthrough after the break, which hopefully should help explain the transition the Atrix can make from phone to desktop to laptop to set-top box. And please excuse our enthusiasm.

MSI Wind Top AE2420 3D all-in-one review

MSI Wind Top AE2420 3D all-in-one review:

When MSI builds an 'all-in-one' PC, it doesn't mess around -- the MSI Wind Top AE2420 3D has everything but the kitchen sink ensconced in a plastic frame. Where most consolidated computers aim for the lowest common denominator with low-power components, MSI's dropped a high-end multimedia bomb here -- a 23.6-inch, 120Hz, 1080p, LED-backlit touchscreen LCD panel paired with a desktop-grade 2.53GHz Core i7-860S processor, Mobility Radeon HD 5730 graphics, a Blu-ray drive, 4GB of RAM, and a terabyte of storage. Active shutter glasses spit out 3D images to your eyes while THX speakers (and a built-in subwoofer) pump out jams, and 802.11 b/g/n WiFi, Bluetooth and USB 3.0 sockets round out a connectivity laundry list. It's got a spec sheet to die for and an equally lethal $1,800 price -- but is the AE2420 3D more than a bucket of primo parts? Is it worth your cash?

7. januar 2011

Google's Android 3.0 Honeycomb for tablets: a guided tour of the UI (video)

Google's Android 3.0 Honeycomb for tablets: a guided tour of the UI (video):

A funny thing happened after Google posted (and subsequently pulled) its Android 3.0 Honeycomb video: T-Mobile celebrated its G-Slate announcement by posting the same video. And about six more after that (to be fair, they're also on the Motorola / Verizon Xoom we demoed). Today it was made official during Verizon's keynote, with Google itself narrating a hands-on demo. We've scrutinized these videos to no end and we think we've come up with the most complete picture of Google's tablet OS experience at this point. Join us after the break for all the goods.

5. januar 2011

ASUS Eee Pad Slider and Transformer are here for those that can't imagine using a tablet without a physical keyboard

ASUS Eee Pad Slider and Transformer are here for those that can't imagine using a tablet without a physical keyboard:

Here they are: ASUS's duo of Tegra 2-powered, 10.1-inch tablets with unique physical keyboards. Starting with the craziest of them, is the Eee Pad Slider (pictured on the left), which reminds us a lot of HTC's old school Shift with its slide out QWERTY keyboard. The device is planned to run Google's Honeycomb, sports a IPS, 1280 x 800-resolution display, and houses mini-HDMI and miniUSB ports as well as a microSD card slot. The 2.2-pound / .5-inch thick slab also has dual cameras -- a 1.2 megapixel front-facing one and a 5 megapixel one with an LED flash on the back. We have to say we love the idea of always having that keyboard around, but if you don't want to drag along a physical keyboard all the time, ASUS has something for you too. It's the Transformer, and like the Eee Pad we saw at Computex, it's a 10.1-inch tablet that will come with a laptop like dock with a full size keyboard and touchpad. The tablet part -- like the Slider -- will run Android 3.0 and packs a dual-core Tegra 2 processor, two cameras, and a 1280 x 800-resolution IPS display, however, the dock has an integrated battery that will keep the tablet running for 16 hours on a charge -- the tablet on its own should last eight. We're obviously aching in our seats here waiting to get these two in our hands so stay tuned for some crazy videos of the two in action -- until then we leave you with the specs after the break.

Update: How much will it cost you to keyboard-ify your slate and how long will you have to wait? ASUS says the Transformer will run between $400 and $700 and the Slider from $500 to $800. Expect them in April and May respectively.




HP updates Envy 17, dv6, and dv7 with Sandy Bridge, gives Mini 210 some new threads

HP updates Envy 17, dv6, and dv7 with Sandy Bridge, gives Mini 210 some new threads:

No surprises here -- HP just updated a bunch of its consumer laptops here at CES, and the biggest change is that the Envy 17 and Pavilion dv6 and dv7 have been kicked over to Intel's Sandy Bridge second-gen Core processors. In addition to the new chips, the Envy 17 is getting HP CoolSense cooling and switchable AMD Radeon 6850M graphics with support for Intel Wireless Display -- pricing and availability haven't been determined yet, but we wouldn't expect it to be cheap. On the other hand, the dv6 and dv7 are mostly the same apart from the processor bump, and they'll be $899 and $999 when they hit on January 9th.

AMD announces first Fusion chips: 10+ hour battery life with DirectX11 graphics

AMD announces first Fusion chips: 10+ hour battery life with DirectX11 graphics:

Is this real? Is this happening? It's been over four years since AMD and ATI completed their $5.4 billion merger with the promise of Fusion hybrid CPU / GPU chips, and after what's seemed like nearly endless delays, the company's delivering here at CES 2011. And it's delivering in a big way -- the first Fusion chips are a direct assault on Intel's Atom and the netbook market, offering what AMD says is better CPU performance, vastly better GPU performance with DirectX11 support, dedicated 1080p HD video processing and HDMI out, and 'all day' battery life that can hit 10 or more hours. There are four total chips in two families built around the new 'Bobcat' CPU core to start: the 'Zacate' E-Series for mainstream laptops, AIOs and small desktops will have an 18W TDP and come in the 1.6GHz dual-core E-350 and the 1.5GHz single-core E-240, while the 'Ontario' C-Series for HD netbooks and 'other emerging form factors' will clock in at 9W TDP and come in the dual-core 1.0GHz C-50 and the single core 1.2GHz C-30. The 'Llano' A-Series designed for mainstream laptops will offer up to four cores and arrive later this year.

We're expecting to see a number of systems based around the E-Series -- the Lenovo X120e and HP Pavilion dm1 have already been announced -- and we're anticipating quite a flood in the days ahead, which we're more than eager to test out. AMD's making some serious claims -- it says 'Fusion processors are, quite simply, the greatest advancement in processing since the introduction of the x86 architecture more than forty years ago' -- and if can deliver on its performance promises, it'll pretty much turn the entire netbook market upside down. What's more, the company says tablets and other embedded devices are coming in the first half of 2011, so things could get seriously interesting. PR after the break.

4. januar 2011

Dell's IPS and multitouch ST2220T finally shipping to tilting monitor seekers

Dell's IPS and multitouch ST2220T finally shipping to tilting monitor seekers:

Well, it took a bit longer than we anticipated for Dell's glorious 21.5-inch multitouch ST2220T monitor with an IPS panel to roll into e-tailers -- last we had heard it was planned for late Fall 2010 -- but we promise you, this one is better late than never. The 1920 x 1080-resolution display is finally available through both Dell and LogicBuy, and if you're anything like us, just a glance at the picture above has you figuring out just how quickly you can get together $310 (there's a $20 discount now and free shipping from LogicBuy). Naturally, the IPS display is said to provide extra wide viewing angles, but perhaps even more enticing is the monitor's A-frame stand, which tilts the screen forward, backward and even flat. Put that all together with its infrared multitouch and you've got a larger than life tablet for gaming and watching Netflix. So, you blowing some of that Christmas cash or what?

31. december 2010

Intel 310 mSATA SSD knows that size matters, fits 80GB into less space than a credit card

Intel 310 mSATA SSD knows that size matters, fits 80GB into less space than a credit card:

Watch out, Toshiba, your tiny SSD modules aren't the only game in town for ludicrously small flash storage anymore. Intel's just announced a new SSD 310 line that offers spectacularly minimal 51mm by 30mm by 5mm dimensions, while retaining X25-class performance (up to 200MBps read and 80MBps write speeds). To give you an idea of what those measurements mean, the industry-standard 2.5-inch form factor, an already diminutive footprint, is eight times larger than these newfangled storage chips. 40GB and 80GB variants of the SSD 310 are shipping out to OEMs already and Lenovo has confirmed it plans to roll these into its next refresh of the venerable ThinkPad laptop line. Prices are set at $99 and $179 (depending on size) when bought in batches of 1,000, though direct sales to end users are predictably off the table for now. Better start saving up for that next ultrathin laptop if you want one.

24. december 2010

VBoxHeadless - Running Virtual Machines With VirtualBox 4.0 On A Headless Ubuntu 10.10 Server

VBoxHeadless - Running Virtual Machines With VirtualBox 4.0 On A Headless Ubuntu 10.10 Server:

VBoxHeadless - Running Virtual Machines With VirtualBox 4.0 On A Headless Ubuntu 10.10 Server

This guide explains how you can run virtual machines with VirtualBox 4.0 on a headless Ubuntu 10.10 server. Normally you use the VirtualBox GUI to manage your virtual machines, but a server does not have a desktop environment. Fortunately, VirtualBox comes with a tool called VBoxHeadless that allows you to connect to the virtual machines over a remote desktop connection, so there's no need for the VirtualBox GUI.

19. december 2010

APTonCD

APTonCD:



APTonCD is a GUI tool that can extract the .deb packages that you have manually installed on your machine and selectively copy them to an ISO image that can be burned to a CD or DVD. The tool can then be used, on another machine, to restore those packages. more>>

11. december 2010

Nexus S review

Nexus S review:

It can be difficult to review a phone like Google's Nexus S in a world already populated by so many outstanding Android devices. Not only does the manufacturer of this phone make a series of handsets that are all essentially the same (the Galaxy S line), but countless other OEMs are cranking away on hardware for the platform. Of course, the Nexus S is a decidedly different phone altogether. Picking up where the company's Nexus One left off, the S continues Google's legacy of creating standalone, 'pure Android' phone experiences, seemingly aimed less at the mainstream and more towards developers. Unlike the failed experiment of the Nexus One, Google appears to be taking a more realistic approach to the S; the phone will be sold through Best Buy (and Carphone Warehouse across the pond), which suggests that the company has bigger plans for this device.

And what a device it is -- the Nexus S boasts a 1GHz Hummingbird CPU, 512MB of RAM, a 4-inch, 800 x 480 curved Super AMOLED display (dubbed the Contour Display), 16GB of storage, a 5 megapixel rear and VGA front-facing camera, and near field communication capabilities. But hardware is only half the story here -- the big news is that the Nexus S showcases the next major evolution of the Android OS, namely, Gingerbread (or version 2.3). The update comes with a slew of new features alongside some UI improvements that show Google isn't slowing down when it comes to pushing its mobile operating system forward. So is the Nexus S a real standout in the Android world, or is it more of the 'me too' tech we've seen lately? Read on after the break for the full Engadget review to find out!