adventures in paranoia with sinatra and sequel

180
with sinatra and sequel Eleanor McHugh @feyeleanor http://github.com/feyeleanor adventures in paranoia rough cut Thursday, 4 April 2013

Upload: eleanor-mchugh

Post on 06-May-2015

390 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Adventures in paranoia with sinatra and sequel

with sinatra and sequel

Eleanor McHugh@feyeleanor

http://github.com/feyeleanor

adventures in paranoia

rough cut

Thursday, 4 April 2013

Page 2: Adventures in paranoia with sinatra and sequel

with sinatra and sequel

Eleanor McHugh@feyeleanor

http://github.com/feyeleanor

adventures in paranoia

rough cut

Thursday, 4 April 2013

Page 3: Adventures in paranoia with sinatra and sequel

with sinatra and sequel

Eleanor McHugh@feyeleanor

http://github.com/feyeleanor

adventures in paranoia

rough cut

Thursday, 4 April 2013

Page 4: Adventures in paranoia with sinatra and sequel

think carefully before doing security

caveat lector

rough cut

Thursday, 4 April 2013

Page 5: Adventures in paranoia with sinatra and sequel

I am not a certified security professional

and it's unlikely you are either

what follows is definitely above our pay grade

and presented to provoke further study

so if privacy truly matters to you - and it should

hire a certified security professional

then follow their advice assiduously

http://slides.games-with-brains.netThursday, 4 April 2013

Page 6: Adventures in paranoia with sinatra and sequel

adventurePronunciation: /əәdˈvɛntʃəә/

noun{mass noun}

an unusual and exciting or daring experience: her recent adventures in Italy

excitement associated with danger or the taking of risks: she travelled the world in search of adventure

a reckless or potentially hazardous action or enterprise.

archaic a commercial venture.

http://slides.games-with-brains.netThursday, 4 April 2013

Page 7: Adventures in paranoia with sinatra and sequel

paranoiaPronunciation: /ˌparəәˈnɔɪəә/

noun{mass noun}

a mental condition characterized by delusions of persecution, unwarranted jealousy, or exaggerated self-importance, typically worked into an organized system. It may be an aspect of chronic personality disorder, of drug abuse, or of a serious condition such as schizophrenia in which the person loses touch with reality.

unjustified suspicion and mistrust of other people: mild paranoia afflicts all prime ministers

http://slides.games-with-brains.netThursday, 4 April 2013

Page 8: Adventures in paranoia with sinatra and sequel

paranoiaPronunciation: /ˌparəәˈnɔɪəә/

noun{mass noun}

the perfectly reasonable belief that someone, somewhere is watching your online behaviour with malicious and/or nefarious intent. It may be a result of reading a Hacking Exposed or Hacking for Dummies publication, experiencing the fallout from identity theft, or mixing with cryptographers and cypherpunks.

justified suspicion and mistrust of other people: chronic paranoia afflicts all information security professionals

http://slides.games-with-brains.netThursday, 4 April 2013

Page 9: Adventures in paranoia with sinatra and sequel

trust no onehow can we believe our visitors are who they claim to be

http://slides.games-with-brains.netThursday, 4 April 2013

Page 10: Adventures in paranoia with sinatra and sequel

trust no onehow can visitors be confident we protect their privacy

http://slides.games-with-brains.netThursday, 4 April 2013

Page 11: Adventures in paranoia with sinatra and sequel

establish a well-known presence

assign globally unique identities

only accept opaque credentials

secure storage wherever identity data rests

secure transport wherever identity data moves

separate authentication and authorisation

http://slides.games-with-brains.netThursday, 4 April 2013

Page 12: Adventures in paranoia with sinatra and sequel

globally unique identities

opaque credentials

secure storage

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 13: Adventures in paranoia with sinatra and sequel

globally unique identities

opaque credentials

secure storage

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 14: Adventures in paranoia with sinatra and sequel

high entropy identifiers

opaque credentials

secure storage

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 15: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

opaque credentials

secure storage

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 16: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

opaque credentials

secure storage

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 17: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

hashed passwords

secure storage

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 18: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

secure storage

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 19: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

secure storage

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 20: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

secure storage

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 21: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

hybrid encryption

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 22: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

OpenSSL::PKey::RSA

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 23: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

OpenSSL::PKey::RSA

OpenSSL::Cipher::AES

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 24: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

OpenSSL::PKey::RSA

OpenSSL::Cipher::AES

single-use keys

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 25: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

OpenSSL::PKey::RSA

OpenSSL::Cipher::AES

single-use keys

secure transport

http://slides.games-with-brains.netThursday, 4 April 2013

Page 26: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

OpenSSL::PKey::RSA

OpenSSL::Cipher::AES

single-use keys

ssl

http://slides.games-with-brains.netThursday, 4 April 2013

Page 27: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

OpenSSL::PKey::RSA

OpenSSL::Cipher::AES

single-use keys

http strict transport security header

http://slides.games-with-brains.netThursday, 4 April 2013

Page 28: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

OpenSSL::PKey::RSA

OpenSSL::Cipher::AES

single-use keys

http strict transport security header

secure cookies

http://slides.games-with-brains.netThursday, 4 April 2013

Page 29: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

OpenSSL::PKey::RSA

OpenSSL::Cipher::AES

single-use keys

http strict transport security header

http-only flag

http://slides.games-with-brains.netThursday, 4 April 2013

Page 30: Adventures in paranoia with sinatra and sequel

SecureRandom.uuid

OpenSSL::Digest::SHA512

iterative workload

OpenSSL::PKey::RSA

OpenSSL::Cipher::AES

single-use keys

http strict transport security

http-only flag

OpenSSL::HMAC

http://slides.games-with-brains.netThursday, 4 April 2013

Page 31: Adventures in paranoia with sinatra and sequel

standard library support for cryptography

ruby crypto

http://slides.games-with-brains.netThursday, 4 April 2013

Page 32: Adventures in paranoia with sinatra and sequel

high-entropy byte stream generator

SecureRandom

http://slides.games-with-brains.netThursday, 4 April 2013

Page 33: Adventures in paranoia with sinatra and sequel

random_bytes

random_number

urlsafe_base64

uuid

http://slides.games-with-brains.netThursday, 4 April 2013

Page 34: Adventures in paranoia with sinatra and sequel

require ‘securerandom’

def random_string min = 8, max = 64length = SecureRandom.random_bytes(max - min)length = SecureRandom.random_bytes(min + length) SecureRandom.random_number length

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 35: Adventures in paranoia with sinatra and sequel

the default security toolkit of the internet

OpenSSL

http://slides.games-with-brains.netThursday, 4 April 2013

Page 36: Adventures in paranoia with sinatra and sequel

SHA2cryptographic hashing algorithm

http://slides.games-with-brains.netThursday, 4 April 2013

Page 37: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class SHA2attr_accessor :rounds, :salt

def initialize options = {}end

def encode valueend

def sign value = nilend

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 38: Adventures in paranoia with sinatra and sequel

def initialize options = {}@digest = OpenSSL::Digest::SHA512.new, options@salt = options[:salt] || 'salted'@rounds = options[:rounds] || 100000@key = options[:signing_key] || ""

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 39: Adventures in paranoia with sinatra and sequel

def initialize options = {}@digest = OpenSSL::Digest::SHA512.new options@salt = options[:salt] || 'salted'@rounds = options[:rounds] || 100000@key = options[:signing_key] || ""

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 40: Adventures in paranoia with sinatra and sequel

def initialize options = {}@digest = OpenSSL::Digest::SHA512.new options@salt = options[:salt] || 'salted'@rounds = options[:rounds] || 100000@key = options[:signing_key] || ""

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 41: Adventures in paranoia with sinatra and sequel

def initialize options = {}@digest = OpenSSL::Digest::SHA512.new options@salt = options[:salt] || 'salted'@rounds = options[:rounds] || 100000@key = options[:signing_key] || ""

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 42: Adventures in paranoia with sinatra and sequel

def initialize options = {}@digest = OpenSSL::Digest::SHA512.new options@salt = options[:salt] || 'salted'@rounds = options[:rounds] || 100000@key = options[:signing_key] || ""

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 43: Adventures in paranoia with sinatra and sequel

def encode [email protected] rounds > 0

@digest << (salt + value)(rounds - 1).times do

@digest << @[email protected]

elsevalue

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 44: Adventures in paranoia with sinatra and sequel

def encode [email protected] rounds > 0

@digest << (salt + value)(rounds - 1).times do

@digest << @[email protected]

elsevalue

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 45: Adventures in paranoia with sinatra and sequel

def encode [email protected] rounds > 0

@digest << (salt + value)(rounds - 1).times do

@digest << @[email protected]

elsevalue

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 46: Adventures in paranoia with sinatra and sequel

def encode [email protected] rounds > 0

@digest << (salt + value)(rounds - 1).times do

@digest << @[email protected]

elsevalue

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 47: Adventures in paranoia with sinatra and sequel

def encode [email protected] rounds > 0

@digest << (salt + value)(rounds - 1).times do

@digest << @[email protected]

elsevalue

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 48: Adventures in paranoia with sinatra and sequel

def encode [email protected] rounds > 0

@digest << (salt + value)(rounds - 1).times do

@digest << @[email protected]

elsevalue

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 49: Adventures in paranoia with sinatra and sequel

def sign value = nilencode value if valueOpenSSL::HMAC.hexdigest @digest, @key, @digest.hexdigest

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 50: Adventures in paranoia with sinatra and sequel

def sign value = nilencode value if valueOpenSSL::HMAC.hexdigest @digest, @key, @digest.hexdigest

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 51: Adventures in paranoia with sinatra and sequel

def sign value = nilencode value if valueOpenSSL::HMAC.hexdigest @digest, @key, @digest.hexdigest

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 52: Adventures in paranoia with sinatra and sequel

class SHA2attr_accessor :rounds, :salt

def initialize options = {}@digest = OpenSSL::Digest::SHA512.new options@salt = options[:salt] || 'salted'@rounds = options[:rounds] || 100000@key = options[:signing_key] || ""

end

def encode [email protected] rounds > 0

@digest << (salt + value)(rounds - 1).times do

@digest << @[email protected]

elsevalue

endend

def sign value = nil encode value if value

OpenSSL::HMAC.hexdigest @digest, @key, @digest.hexdigestend

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 53: Adventures in paranoia with sinatra and sequel

AESsingle-key symmetric encryption

http://slides.games-with-brains.netThursday, 4 April 2013

Page 54: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class AESattr_reader :result, :key, :iv

def initialize options = {}end

def encode data = ""end

def decode cipher_text = ""end

def encode_and_pack dataend

def unpack_and_decode cipher_textend

privatedef update data = ""end

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 55: Adventures in paranoia with sinatra and sequel

def update data = ""@result = @cipher.update data@result << @cipher.final

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 56: Adventures in paranoia with sinatra and sequel

def update data = ""@result = @cipher.update data@result << @cipher.final

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 57: Adventures in paranoia with sinatra and sequel

def update data = ""@result = @cipher.update data@result << @cipher.final

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 58: Adventures in paranoia with sinatra and sequel

def initialize options = {}@cipher = OpenSSL::Cipher::AES.new 256, :CBC@iv = if options[:iv]

@cipher.iv = options[:iv]else

@cipher.random_ivend

@key = if options[:key]@cipher.key = options[:key]

[email protected]_key

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 59: Adventures in paranoia with sinatra and sequel

def initialize options = {}@cipher = OpenSSL::Cipher::AES.new 256, :CBC@iv = if options[:iv]

@cipher.iv = options[:iv]else

@cipher.random_ivend

@key = if options[:key]@cipher.key = options[:key]

[email protected]_key

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 60: Adventures in paranoia with sinatra and sequel

def initialize options = {}@cipher = OpenSSL::Cipher::AES.new 256, :CBC@iv = if options[:iv]

@cipher.iv = options[:iv]else

@cipher.random_ivend

@key = if options[:key]@cipher.key = options[:key]

[email protected]_key

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 61: Adventures in paranoia with sinatra and sequel

def initialize options = {}@cipher = OpenSSL::Cipher::AES.new 256, :CBC@iv = if options[:iv]

@cipher.iv = options[:iv]else

@cipher.random_ivend

@key = if options[:key]@cipher.key = options[:key]

[email protected]_key

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 62: Adventures in paranoia with sinatra and sequel

def encode data = ""@[email protected]@cipher.key = [email protected] = ivupdate(data.to_s rescue "")

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 63: Adventures in paranoia with sinatra and sequel

def encode data = ""@[email protected]@cipher.key = [email protected] = ivupdate(data.to_s rescue "")

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 64: Adventures in paranoia with sinatra and sequel

def encode data = ""@[email protected]@cipher.key = [email protected] = ivupdate(data.to_s rescue "")

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 65: Adventures in paranoia with sinatra and sequel

def encode data = ""@[email protected]@cipher.key = [email protected] = ivupdate(data.to_s rescue "")

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 66: Adventures in paranoia with sinatra and sequel

def decode cipher_text = ""length = cipher_text.length rescue 0@result = if length > 0

@[email protected]@cipher.key = [email protected] = ivcipher_text = update cipher_textcipher_text if cipher_text.length > 0

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 67: Adventures in paranoia with sinatra and sequel

def decode cipher_text = ""length = cipher_text.length rescue 0@result = if length > 0

@[email protected]@cipher.key = [email protected] = ivcipher_text = update cipher_textcipher_text if cipher_text.length > 0

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 68: Adventures in paranoia with sinatra and sequel

def decode cipher_text = ""length = cipher_text.length rescue 0@result = if length > 0

@[email protected]@cipher.key = [email protected] = ivcipher_text = update cipher_textcipher_text if cipher_text.length > 0

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 69: Adventures in paranoia with sinatra and sequel

def decode cipher_text = ""length = cipher_text.length rescue 0@result = if length > 0

@[email protected]@cipher.key = [email protected] = ivcipher_text = update cipher_textcipher_text if cipher_text.length > 0

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 70: Adventures in paranoia with sinatra and sequel

def decode cipher_text = ""length = cipher_text.length rescue 0@result = if length > 0

@[email protected]@cipher.key = [email protected] = ivcipher_text = update cipher_textcipher_text if cipher_text.length > 0

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 71: Adventures in paranoia with sinatra and sequel

def decode cipher_text = ""length = cipher_text.length rescue 0@result = if length > 0

@[email protected]@cipher.key = [email protected] = ivcipher_text = update cipher_textcipher_text if cipher_text.length > 0

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 72: Adventures in paranoia with sinatra and sequel

def decode cipher_text = ""length = cipher_text.length rescue 0@result = if length > 0

@[email protected]@cipher.key = [email protected] = ivcipher_text = update cipher_textcipher_text if cipher_text.length > 0

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 73: Adventures in paranoia with sinatra and sequel

def encode_and_pack data[iv, encode(data)].pack 'mm'

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 74: Adventures in paranoia with sinatra and sequel

def encode_and_pack data[iv, encode(data)].pack 'mm'

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 75: Adventures in paranoia with sinatra and sequel

def encode_and_pack data[iv, encode(data)].pack 'mm'

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 76: Adventures in paranoia with sinatra and sequel

def unpack_and_decode cipher_text = ""cipher_elements = cipher_text.unpack 'mm'if cipher_elements.length > 0

c = AES.new iv: cipher_elements[0], key: key@result = c.decode cipher_elements[1]

endrescue Exception => e

nilend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 77: Adventures in paranoia with sinatra and sequel

def unpack_and_decode cipher_text = ""cipher_elements = cipher_text.unpack 'mm'if cipher_elements.length > 0

c = AES.new iv: cipher_elements[0], key: key@result = c.decode cipher_elements[1]

endrescue Exception => e

nilend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 78: Adventures in paranoia with sinatra and sequel

def unpack_and_decode cipher_text = ""cipher_elements = cipher_text.unpack 'mm'if cipher_elements.length > 0

c = AES.new iv: cipher_elements[0], key: key@result = c.decode cipher_elements[1]

endrescue Exception => e

nilend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 79: Adventures in paranoia with sinatra and sequel

def unpack_and_decode cipher_text = ""cipher_elements = cipher_text.unpack 'mm'if cipher_elements.length > 0

c = AES.new iv: cipher_elements[0], key: key@result = c.decode cipher_elements[1]

endrescue Exception => e

nilend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 80: Adventures in paranoia with sinatra and sequel

RSA2-key asymmetric encryption

http://slides.games-with-brains.netThursday, 4 April 2013

Page 81: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class RSAattr_reader :result, :key

def initialize opts = {}@key = OpenSSL::PKey::RSA.new(opts[:key] || opts[:keysize])

end

def [email protected]_key.to_pem

end

def [email protected]_pem

end

def encode data@result = @key.public_encrypt(data.to_s rescue "")

end

def decode cipher_text@result = @key.private_decrypt(cipher_text.to_s rescue "")

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 82: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class RSAattr_reader :result, :key

def initialize opts = {}@key = OpenSSL::PKey::RSA.new(opts[:key] || opts[:keysize])

end

def [email protected]_key.to_pem

end

def [email protected]_pem

end

def encode data@result = @key.public_encrypt(data.to_s rescue "")

end

def decode cipher_text@result = @key.private_decrypt(cipher_text.to_s rescue "")

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 83: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class RSAattr_reader :result, :key

def initialize opts = {}@key = OpenSSL::PKey::RSA.new(opts[:key] || opts[:keysize])

end

def [email protected]_key.to_pem

end

def [email protected]_pem

end

def encode data@result = @key.public_encrypt(data.to_s rescue "")

end

def decode cipher_text@result = @key.private_decrypt(cipher_text.to_s rescue "")

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 84: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class RSAattr_reader :result, :key

def initialize opts = {}@key = OpenSSL::PKey::RSA.new(opts[:key] || opts[:keysize])

end

def [email protected]_key.to_pem

end

def [email protected]_pem

end

def encode data@result = @key.public_encrypt(data.to_s rescue "")

end

def decode cipher_text@result = @key.private_decrypt(cipher_text.to_s rescue "")

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 85: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class RSAattr_reader :result, :key

def initialize opts = {}@key = OpenSSL::PKey::RSA.new(opts[:key] || opts[:keysize])

end

def [email protected]_key.to_pem

end

def [email protected]_pem

end

def encode data@result = @key.public_encrypt(data.to_s rescue "")

end

def decode cipher_text@result = @key.private_decrypt(cipher_text.to_s rescue "")

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 86: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class RSAattr_reader :result, :key

def initialize opts = {}@key = OpenSSL::PKey::RSA.new(opts[:key] || opts[:keysize])

end

def [email protected]_key.to_pem

end

def [email protected]_pem

end

def encode data@result = @key.public_encrypt(data.to_s rescue "")

end

def decode cipher_text@result = @key.private_decrypt(cipher_text.to_s rescue "")

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 87: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class RSAattr_reader :result, :key

def initialize opts = {}@key = OpenSSL::PKey::RSA.new(opts[:key] || opts[:keysize])

end

def [email protected]_key.to_pem

end

def [email protected]_pem

end

def encode data@result = @key.public_encrypt(data.to_s rescue "")

end

def decode cipher_text@result = @key.private_decrypt(cipher_text.to_s rescue "")

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 88: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class RSAattr_reader :result, :key

def initialize opts = {}@key = OpenSSL::PKey::RSA.new(opts[:key] || opts[:keysize])

end

def [email protected]_key.to_pem

end

def [email protected]_pem

end

def encode data@result = @key.public_encrypt(data.to_s rescue "")

end

def decode cipher_text@result = @key.private_decrypt(cipher_text.to_s rescue "")

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 89: Adventures in paranoia with sinatra and sequel

require ‘openssl’

class RSAattr_reader :result, :key

def initialize opts = {}@key = OpenSSL::PKey::RSA.new(opts[:key] || opts[:keysize])

end

def [email protected]_key.to_pem

end

def [email protected]_pem

end

def encode data@result = @key.public_encrypt(data.to_s rescue "")

end

def decode cipher_text@result = @key.private_decrypt(cipher_text.to_s rescue "")

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 90: Adventures in paranoia with sinatra and sequel

encryption-aware tables in Sequel

encrypted datastores

http://slides.games-with-brains.netThursday, 4 April 2013

Page 91: Adventures in paranoia with sinatra and sequel

(this is not a sequel talk)

encrypted datastores

http://slides.games-with-brains.netThursday, 4 April 2013

Page 92: Adventures in paranoia with sinatra and sequel

(we're just using it for its friendly DDL)

encrypted datastores

http://slides.games-with-brains.netThursday, 4 April 2013

Page 93: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin :schemaplugin :validation_helpers

set_schema doprimary_key :idString :nameString :email_address

index :name, unique: trueindex :email_address, unique: true

end

def validatesupervalidates_unique :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 94: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin!:schemaplugin :validation_helpers

set_schema doprimary_key :idString :nameString :email_address

index :name, unique: trueindex :email_address, unique: true

end

def validatesupervalidates_unique :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 95: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin!:schemaplugin :validation_helpers

set_schema doprimary_key :idString :nameString :email_address

index :name, unique: trueindex :email_address, unique: true

end

def validatesupervalidates_unique :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 96: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin!:schemaplugin!:validation_helpers

set_schema doprimary_key :idString :nameString :email_address

index :name, unique: trueindex :email_address, unique: true

end

def validatesupervalidates_unique :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 97: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin!:schemaplugin!:validation_helpers

set_schema doprimary_key :idString :nameString :email_address

index :name, unique: trueindex :email_address, unique: true

end

def validatesupervalidates_unique :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 98: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin :schemaplugin :validation_helpers

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 99: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin :schemaplugin :validation_helpers

set_schema doprimary_key!:id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 100: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin :schemaplugin :validation_helpers

set_schema doprimary_key!:id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 101: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin :schemaplugin :validation_helpers

set_schema doprimary_key!:id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 102: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin :schemaplugin :validation_helpers

set_schema doprimary_key!:id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 103: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin :schemaplugin :validation_helpers

set_schema doprimary_key!:id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index! ! :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 104: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin :schemaplugin :validation_helpers

set_schema doprimary_key!:id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index! ! :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 105: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin :schemaplugin :validation_helpers

set_schema doprimary_key!:id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index! ! :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 106: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelplugin! :schemaplugin! :validation_helpers

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 107: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 108: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 109: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin!:validation_helpersmod.plugin!:schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 110: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Model

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 111: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 112: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 113: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 114: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 115: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 116: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

end

def == entityself[:id] == entity.id rescue false

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 117: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

end

def == entityself[:id] == entity.id rescue false

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 118: Adventures in paranoia with sinatra and sequel

module Modeldef self.included mod

mod.plugin :validation_helpersmod.plugin :schemamod.module_eval <<-ACCESSOR, __FILE__, __LINE__ + 1

def self.retrieve id#{mod}.where(id: id).first

endACCESSOR

end

def == entityself[:id] == entity.id rescue false

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 119: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Model

set_schema doprimary_key!:id, type: :varchar, auto_increment: false, unique: trueString :nameString :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

unrestrict_primary_key

def validatesupervalidates_unique :id, :name, :email_address

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 120: Adventures in paranoia with sinatra and sequel

module Modelrequire 'securerandom'

def generate_idSecureRandom.uuid

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 121: Adventures in paranoia with sinatra and sequel

module Modelrequire 'securerandom'

def generate_idSecureRandom.uuid

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 122: Adventures in paranoia with sinatra and sequel

module Modelrequire 'securerandom'

def generate_idSecureRandom.uuid

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 123: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Model

set_schema doprimary_key! :id, type: :varchar, auto_increment: false, unique: trueString :nameString :retrieval_email

index :id, unique: trueindex :name, unique: trueindex :retrieval_email, unique: true

end

unrestrict_primary_key

def before_creategenerate_idsuper

end

def validatesupervalidates_unique :id, :name, :retrieval_email

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 124: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Model

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString! ! :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 125: Adventures in paranoia with sinatra and sequel

module EncryptedModeldef encrypted_fields fields = [], options = {}

options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0end

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 126: Adventures in paranoia with sinatra and sequel

module EncryptedModeldef encrypted_fields fields = [], options = {}

options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0end

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 127: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Modelextend EncryptedModel

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString! ! :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

encrypted_fields :email_addressend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 128: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Modelextend EncryptedModel

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString! ! :email_address

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

encrypted_fields! :email_addressend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 129: Adventures in paranoia with sinatra and sequel

with encrypted search

field encryption

http://slides.games-with-brains.netThursday, 4 April 2013

Page 130: Adventures in paranoia with sinatra and sequel

automatically encrypt on storing

automatically decrypt on retrieval

support equality searches

http://slides.games-with-brains.netThursday, 4 April 2013

Page 131: Adventures in paranoia with sinatra and sequel

def encrypted_fields fields = [], options = {}options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0

configure_field_encryptionadd_field_validationenable_equality_searches optionsadd_field_accessors fields

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 132: Adventures in paranoia with sinatra and sequel

def encrypted_fields fields = [], options = {}options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0

configure_field_encryptionadd_field_validationenable_equality_searches optionsadd_field_accessors fields

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 133: Adventures in paranoia with sinatra and sequel

def configure_field_encryptionself.module_eval <<-CIPHER, __FILE__, __LINE__ + 1

def symmetric_ciphercipher = if self[:key]

AES.new key: self[:key], iv: self[:iv]else

AES.newendself[:key] ||= cipher.keyself[:iv] ||= cipher.ivcipher

endCIPHER

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 134: Adventures in paranoia with sinatra and sequel

def configure_field_encryptionself.module_eval <<-CIPHER, __FILE__, __LINE__ + 1

def symmetric_ciphercipher = if self[:key]

AES.new key: self[:key], iv: self[:iv]else

AES.newendself[:key] ||= cipher.keyself[:iv] ||= cipher.ivcipher

endCIPHER

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 135: Adventures in paranoia with sinatra and sequel

def configure_field_encryptionself.module_eval <<-CIPHER, __FILE__, __LINE__ + 1

def symmetric_ciphercipher = if self[:key]

AES.new key: self[:key], iv: self[:iv]else

AES.newendself[:key] ||= cipher.keyself[:iv] ||= cipher.ivcipher

endCIPHER

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 136: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Modelextend EncryptedModel

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString! ! :email_addressblob :key, null: trueblob :iv, null: true

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

encrypted_fields! :email_addressend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 137: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Modelextend EncryptedModel

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString! ! :email_addressblob! ! :key, null: trueblob :iv, null: true

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

encrypted_fields! :email_addressend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 138: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Modelextend EncryptedModel

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString! ! :email_addressblob! ! :key, null: trueblob! ! :iv, null: true

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: true

end

encrypted_fields! :email_addressend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 139: Adventures in paranoia with sinatra and sequel

def configure_field_encryptionself.module_eval <<-CIPHER, __FILE__, __LINE__ + 1

def symmetric_ciphercipher = if self[:key]

AES.new key: self[:key], iv: self[:iv]else

AES.newendself[:key] ||= cipher.keyself[:iv] ||= cipher.ivcipher

endCIPHER

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 140: Adventures in paranoia with sinatra and sequel

def configure_field_encryptionself.module_eval <<-CIPHER, __FILE__, __LINE__ + 1

def symmetric_ciphercipher = if self[:key]

AES.new key: self[:key], iv: self[:iv]else

AES.newendself[:key] ||= cipher.keyself[:iv] ||= cipher.ivcipher

endCIPHER

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 141: Adventures in paranoia with sinatra and sequel

def configure_field_encryptionself.module_eval <<-CIPHER, __FILE__, __LINE__ + 1

def symmetric_ciphercipher = if self[:key]

AES.new key: self[:key], iv: self[:iv]else

AES.newendself[:key] ||= cipher.keyself[:iv] ||= cipher.ivcipher

endCIPHER

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 142: Adventures in paranoia with sinatra and sequel

def configure_field_encryptionself.module_eval <<-CIPHER, __FILE__, __LINE__ + 1

def symmetric_ciphercipher = if self[:key]

AES.new key: self[:key], iv: self[:iv]else

AES.newendself[:key] ||= cipher.keyself[:iv] ||= cipher.ivcipher

endCIPHER

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 143: Adventures in paranoia with sinatra and sequel

def configure_field_encryptionself.module_eval <<-CIPHER, __FILE__, __LINE__ + 1

def symmetric_ciphercipher = if self[:key]

AES.new key: self[:key], iv: self[:iv]else

AES.newendself[:key] ||= cipher.keyself[:iv] ||= cipher.ivcipher

endCIPHER

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 144: Adventures in paranoia with sinatra and sequel

def configure_field_encryptionself.module_eval <<-CIPHER, __FILE__, __LINE__ + 1

def symmetric_ciphercipher = if self[:key]

AES.new key: self[:key], iv: self[:iv]else

AES.newendself[:key] ||= cipher.keyself[:iv] ||= cipher.ivcipher

endCIPHER

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 145: Adventures in paranoia with sinatra and sequel

def encrypted_fields fields = [], options = {}options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0

configure_field_encryptionadd_field_validationenable_equality_searches optionsadd_field_accessors fields

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 146: Adventures in paranoia with sinatra and sequel

def encrypted_fields fields = [], options = {}options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0

configure_field_encryptionself.module_eval <<-VALIDATION, __FILE__, __LINE__ + 1

def validates_encrypted_field_presence *fieldsvalidates_presence #{

fields.collect{ |f| "#{f}_key"}.inspect}

endVALIDATIONadd_field_accessorsenable_equality_searches

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 147: Adventures in paranoia with sinatra and sequel

def encrypted_fields fields = [], options = {}options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0

configure_field_encryptionself.module_eval <<-VALIDATION, __FILE__, __LINE__ + 1

def validates_encrypted_field_presence *fieldsvalidates_presence #{

fields.collect{ |f| "#{f}_key"}.inspect}

endVALIDATIONadd_field_accessorsenable_equality_searches

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 148: Adventures in paranoia with sinatra and sequel

def encrypted_fields fields = [], options = {}options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0

configure_field_encryptionself.module_eval <<-VALIDATION, __FILE__, __LINE__ + 1

def validates_encrypted_field_presence *fieldsvalidates_presence #{

fields.collect{ |f| "#{f}_key"}.inspect}

endVALIDATIONadd_field_accessorsenable_equality_searches

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 149: Adventures in paranoia with sinatra and sequel

def encrypted_fields fields = [], options = {}options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0

configure_field_encryptionadd_field_validationenable_equality_searches optionsadd_field_accessors fields

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 150: Adventures in paranoia with sinatra and sequel

def enable_equality_searches options = {}self.module_eval <<-SEARCH, __FILE__, __LINE__ + 1

def self.search_key v@@index_key = "#{options[:signing_key]}"@@rounds = #{options[:rounds]}@@salt = "#{options[:salt]}"if v && @@index_key

digest = SHA512.new key: @@index_key, rounds: @@rounds, salt: @@saltdigest.encode vdigest.sign

elsev

endend

def search_key vself.class.search_key v

endSEARCH

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 151: Adventures in paranoia with sinatra and sequel

def enable_equality_searches options = {}self.module_eval <<-SEARCH, __FILE__, __LINE__ + 1

def self.search_key v@@index_key = "#{options[:signing_key]}"@@rounds = #{options[:rounds]}@@salt = "#{options[:salt]}"if v && @@index_key

digest = SHA512.new key: @@index_key, rounds: @@rounds, salt: @@saltdigest.encode vdigest.sign

elsev

endend

def search_key vself.class.search_key v

endSEARCH

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 152: Adventures in paranoia with sinatra and sequel

def enable_equality_searches options = {}self.module_eval <<-SEARCH, __FILE__, __LINE__ + 1

def self.search_key v@@index_key = "#{options[:signing_key]}"@@rounds = #{options[:rounds]}@@salt = "#{options[:salt]}"if v && @@index_key

digest = SHA512.new key: @@index_key, rounds: @@rounds, salt: @@saltdigest.encode vdigest.sign

elsev

endend

def search_key vself.class.search_key v

endSEARCH

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 153: Adventures in paranoia with sinatra and sequel

def enable_equality_searches options = {}self.module_eval <<-SEARCH, __FILE__, __LINE__ + 1

def self.search_key v@@index_key = "#{options[:signing_key]}"@@rounds = #{options[:rounds]}@@salt = "#{options[:salt]}"if v && @@index_key

digest = SHA512.new key: @@index_key, rounds: @@rounds, salt: @@saltdigest.encode vdigest.sign

elsev

endend

def search_key vself.class.search_key v

endSEARCH

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 154: Adventures in paranoia with sinatra and sequel

def enable_equality_searches options = {}self.module_eval <<-SEARCH, __FILE__, __LINE__ + 1

def self.search_key v@@index_key = "#{options[:signing_key]}"@@rounds = #{options[:rounds]}@@salt = "#{options[:salt]}"if v && @@index_key

digest = SHA512.new key: @@index_key, rounds: @@rounds, salt: @@saltdigest.encode vdigest.sign

elsev

endend

def search_key vself.class.search_key v

endSEARCH

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 155: Adventures in paranoia with sinatra and sequel

def enable_equality_searches options = {}self.module_eval <<-SEARCH, __FILE__, __LINE__ + 1

def self.search_key v@@index_key = "#{options[:signing_key]}"@@rounds = #{options[:rounds]}@@salt = "#{options[:salt]}"if v && @@index_key

digest = SHA512.new key: @@index_key, rounds: @@rounds, salt: @@saltdigest.encode vdigest.sign

elsev

endend

def search_key vself.class.search_key v

endSEARCH

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 156: Adventures in paranoia with sinatra and sequel

def enable_equality_searches options = {}self.module_eval <<-SEARCH, __FILE__, __LINE__ + 1

def self.search_key v@@index_key = "#{options[:signing_key]}"@@rounds = #{options[:rounds]}@@salt = "#{options[:salt]}"if v && @@index_key

digest = SHA512.new key: @@index_key, rounds: @@rounds, salt: @@saltdigest.encode vdigest.sign

elsev

endend

def search_key vself.class.search_key v

endSEARCH

end

http://slides.games-with-brains.netThursday, 4 April 2013

Page 157: Adventures in paranoia with sinatra and sequel

def encrypted_fields fields = [], options = {}options = { rounds: 100000, salt: "", signing_key: "" }.merge optionsif fields.length > 0

configure_field_encryptionadd_field_validationenable_equality_searches optionsadd_field_accessors fields

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 158: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 159: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 160: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 161: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 162: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 163: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 164: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 165: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 166: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 167: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 168: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 169: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_fingerprint] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 170: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_key] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 171: Adventures in paranoia with sinatra and sequel

def add_field_accessors fieldsfields.each do |field|

self.module_eval <<-ACCESSORS, __FILE__, __LINE__ + 1def #{field}

v = symmetric_cipher.decode self[:#{field}]#{field.capitalize}.where(id: v).first

end

def #{field}= valueself[:#{field}] = symmetric_cipher.encode valueself[:#{field}_key] = search_key v

end

def #{field}_fingerprintself[:#{field}_fingerprint]

endACCESSORS

endend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 172: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Modelextend EncryptedModel

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString! ! :email_addressString :email_address_fingerprintblob :key, null: trueblob :iv, null: true

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: trueindex :email_address_fingerprint

end

encrypted_fields! :email_addressend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 173: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Modelextend EncryptedModel

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString! ! :email_addressString! ! :email_address_fingerprintblob :key, null: trueblob :iv, null: true

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: trueindex :email_address_fingerprint

end

encrypted_fields! :email_addressend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 174: Adventures in paranoia with sinatra and sequel

class Account < Sequel::Modelinclude Modelextend EncryptedModel

set_schema doprimary_key :id, type: :varchar, auto_increment: false, unique: trueString :nameString! ! :email_addressString! ! :email_address_fingerprintblob :key, null: trueblob :iv, null: true

index :id, unique: trueindex :name, unique: trueindex :email_address, unique: trueindex! ! :email_address_fingerprint

end

encrypted_fields! :email_addressend

http://slides.games-with-brains.netThursday, 4 April 2013

Page 175: Adventures in paranoia with sinatra and sequel

episode 2 preview

http://slides.games-with-brains.netThursday, 4 April 2013

Page 176: Adventures in paranoia with sinatra and sequel

securing table access with hybrid cryptography

table encryption

http://slides.games-with-brains.netThursday, 4 April 2013

Page 177: Adventures in paranoia with sinatra and sequel

securing table access with hybrid cryptography

table encryption

http://slides.games-with-brains.netThursday, 4 April 2013

Page 178: Adventures in paranoia with sinatra and sequel

encrypting & signing cookies with rack

transport security

http://slides.games-with-brains.netThursday, 4 April 2013

Page 179: Adventures in paranoia with sinatra and sequel

federated private data with sinatra

service isolation

http://slides.games-with-brains.netThursday, 4 April 2013

Page 180: Adventures in paranoia with sinatra and sequel

with sinatra and sequel

http://slides.games-with-brains.net/

adventures in paranoia

Thursday, 4 April 2013