Encryption and stuffs
PHParlor GBG #1, 2014-08-28
Disclaimer
- IT-security is fun
- IT-security is hard
- Don't take my advice!
Case:
Statistics for Sweden's national test
(nationella provet)
Simple system
- Teachers enter students grades
- Creators of the test gets statistics
For ease of use: Teachers can enter students name
Requirement:
- Username and password only
- Password reset needs to work
First version
- Have to meet deadline
- What can we do in a short period of time?
Solution:
- Two tables which needed encryption
- Straight AES with static key per table
- Wipe keys as soon as teachers are finished
Pros
- We delivered in time
- We can't directly see names
- An attacker needs disk access for keys
- No extra work for the user (teacher)
Cons
- Doesn't really provide anonymity
- Teacher information was not encrypted
- Same key for every user
- ?? Probably lot's more
Second version
- The basic code is in place
- How can we improve this?
- Without adding any complexity for the user
"Good enough" solution:
- Treat username (email) as a secret
(pass through PBKDF2 before storing)
- Use real username as part of AES key w/ static keys
- Store real username in memcache during the session
Pros
- Resetting password still works!
- Username / email is hashed before storage
- After signing out (or restarting memcache) keys are gone
- (still) No extra work for the user
Cons
- During a session, user and key is known
- Hard to find users to give them support
- Still not really anonymous?
// Event listener
public function prePersist(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof EncryptedEntity) {
$this->encryption->encrypt($entity);
}
}
// Encryption service
public function encrypt(EncryptedEntity $entity)
{
$fields = $entity->getSecureFields();
foreach ($fields as $field) {
if (!$entity->isSecure($field)) {
// ...
}
}
}
// Encrypted entity
public function setName($name)
{
$this->name = $name;
$this->setInsecure('name');
return $this;
}