Skeleton Key Cocoaheads presentation
Here’s the contents of the presentation i gave last night at cocoaheads sydney, for anyone who’s interested. Exclamation marks are slide separators, to suit my presentation app, Impromptu (impromptuapp.com).
Also the source can be found here: https://github.com/chrishulbert/CHBgDropboxSync
Skeleton Key
====
* Dropbox
* Cryptography
* Marketing
!
Dropbox
=======
* Background sync
* Fully automatic
* Suppresses errors
* One folder, yaml files
!
Sync strategy
----
* Compare folders
* Both, same: nothing
* Both, different date: newer wins
* Different: depends on last sync state
!
Different
-------
If missing locally:
Present at last sync = it's been deleted locally, so delete remotely
Missing at last sync = it's been added remotely, so download.
!
Different 2
---
If missing remotely:
Present at last sync = it's been deleted remotely, so delete locally
Missing at last sync = it's been added locally, so upload.
!
Edge cases
----
Since the last sync data is only ever used to justify a
deletion, safe to clear it any time to avoid edge cases.
Eg clearing dropbox, linking, unlinking.
!
Cryptography
============
* Master password is validated using bCrypt
* All passwords are encrypted by AES
* The AES key is derived from the master pass using PBKDF2
!
bCrypt
------
Only used to verify the master pass, nothing else. One way
slow hash designed to not be GPU-able.
Uses JFBCrypt:
http://www.jayfuerstenberg.com/blog/bcrypt-in-objective-c
5 rounds takes ~0.1s on iPhone 4
!
Storing a password
------
salt = [JFBCrypt generateSaltWithNumberOfRounds:5];
hash = [JFBCrypt hashPassword:clearPassword withSalt:salt];
Store both the above strings
!
Validating
----------
test = [JFBCrypt hashPassword:clearPassword
withSalt:salt];
valid = [test isEqualToString:hash];
!
PBKDF2
------
An industry-standard (eg OpenSSL) way to derive a key
from a passphrase/word.
Using Security framework, and CommonCrypto/CommonKeyDerivation.h
We're making a 32byte / 256bit key.
!
Calibrating
-------
So that we know how many rounds to make it take ~0.1s:
int rounds = CCCalibratePBKDF(kCCPBKDF2,
clearPassword.length, keySalt.length,
kCCPRFHmacAlgSHA256, 32, 100);
!
Salt
----
- (NSData*)generateSalt256 {
unsigned char salt[32];
for (int i=0; i<32; i++) {
salt[i] = (unsigned char)arc4random();
}
return [NSData dataWithBytes:salt length:32];
}
!
Deriving
-----
NSData* myPassData = [clearPassword
dataUsingEncoding:NSUTF8StringEncoding];
unsigned char rawKey[32];
CCKeyDerivationPBKDF(kCCPBKDF2, myPassData.bytes,
myPassData.length, keySalt.bytes, keySalt.length,
kCCPRFHmacAlgSHA256, rounds, rawKey, 32);
return [NSMutableData dataWithBytes:rawKey length:32];
!
AES
---
Also using Apple's Security framework's CommonCrypto
Using NSData+CommonCrypto helpers:
https://github.com/AlanQuatermain/aqtoolkit
!
Encrypt
---
- (NSString*)encrypt:(NSString*)clear {
NSData* clearData = [clear
dataUsingEncoding:NSUTF8StringEncoding];
NSData* crypto = [clearData
AES256EncryptedDataUsingKey:key error:nil];
return [crypto base64EncodedString];
}
!
Decrypt
----
- (NSString*)decrypt:(NSString*)crypto {
NSData* cryptoData = [NSData
dataFromBase64String:crypto];
NSData* clearData = [cryptoData
decryptedAES256DataUsingKey:key
error:nil];
return [[NSString alloc] initWithData:clearData
encoding:NSUTF8StringEncoding];
}
!
Marketing
----
* Nobody responds to requests for reviews.
* Ads driving people to your promo-site costs more than income.
* Promo site with videos, screenshots, and features.
* Sells best when free!
!
So I got some advice..
---
Patio11 (HN)
!
Next time
----
* Find popular forum
* Working with them, make app
* Make placeholder page, collect emails, have shareables
* Determine if worth proceeding
* Attract via forums and ads
* Emails with updates
* Done
* Post launch, still interact, and email updates
* Emails link to forum for discussion
!
Please visit
-----
App: SkeletonKeyApp.com
Presentation: splinter.com.au