Upload
vividcortex
View
847
Download
2
Embed Size (px)
Citation preview
Intro & Logistics
• Contact me at @xaprb or [email protected]
• Ask questions anytime
• Slides will be posted
Data Encryption
• It’s possible to encrypt at any desired layer in the stack
• You can encrypt “close to the user” or “far from the user”
• It’s also possible to skip layers, e.g. encrypt the block device, encrypt the transport, and leave cleartext everywhere else
Block Device
Filesystem
Database
Service
Application
From A Layer Down
• In general, in many cases when you encrypt at some layer, it’s relatively straightforward to ensure it remains encrypted at lower layers.
• Ideally for the user’s security, you want encryption as far up the stack as possible.
• Ideally for the app’s functionality, you want encryption as far down the stack as possible.
Block Device
Filesystem
Database
Service
Application
Convenience Versus Security
• Anywhere data needs to be understood and manipulated, it must be available in cleartext.
• Users need the data to be decrypted for them in the application, obviously.
• What about other places?
Block Device
Filesystem
Database
Service
Application
Encryption In The App or User Interface
• Example: LastPass.
• Consequence: services can’t do useful things.
• This is impractical for most purposes.
• Consider e.g. using Dropbox to embed slides in a blog post.
Block Device
Filesystem
Database
Service
Application
Encryption In The Service
• Data is available in plaintext in the service, so the service can do useful things.
• Anything that can access the service can access the unencrypted data.
Block Device
Filesystem
Database
Service
Application
Encryption In The Database
• This is rather nuanced. Data can be encrypted in many ways in the database.
• The easiest way to think about this: as a database client, do I need to bring my own key to unlock my data, or is the key resident in the database?
Block Device
Filesystem
Database
Service
Application
Send My Key, Or Keep It Private?
• This is equivalent in some ways to encrypting at a higher or lower level in the stack.
• However, the “send my key” strategy has an important consequence: the key is present across more than one layer in the stack.
• If you send a key to a lower level, you lose control over it. (For example it can be viewed in SHOW PROCESSLIST or logged to disk in plaintext.)
Encryption in the Filesystem or Block Device
• This is often a way of implementing “at-rest” encryption.
Block Device
Filesystem
Database
Service
Application
Encrypt at-rest or in-transit?
• PCI specifies two kinds of encryption, “at-rest” and “data in motion.”
• Sometimes companies just ensure they meet these requirements to protect themselves from consequences.
• The reality is, even if data is encrypted both ways, there are easy ways to “checkbox comply” without significantly making access to the data safer and reducing attack surface.
• I believe it is much more important to think about who can get access and how, and address the greatest threats to the end user (not just the vendor).
MySQL Encryption Functions
• MySQL offers a few encryption functions in SQL.
• Many of them are deprecated.
• AES is supported, and is the only one you should use.
• Any encryption using SQL functions is “send-my-key.”
• See https://dev.mysql.com/doc/refman/5.6/en/encryption-functions.html
Key Management
• Key management is an important element of an encryption strategy.
• How are keys secured?
• How are they made available when/where needed? Are they on-disk? Are they in-memory only? Who or what gives them to a user, app, or service that needs them?
• How are they rotated and expired?
• Further reading:
• PKI
• http://aws.amazon.com/kms/
Encryption with Go
• Go’s database/sql package supports interfaces that enable easy in-service encryption.
• The encryption is transparent to the programmer.
• It is not a “send-my-key” strategy. The key is not leaked outside the Go process.
• See “Using Built-In Interfaces” in “The Ultimate Guide To Building Database-Driven Apps with Go”
Block Device
Filesystem
Database
Service
Application
To Implement
• You need to implement a type that satisfies two of Go’s stdlib interfaces.
• driver.Valuer influences how values are transformed as they are sent to the database.
• sql.Scanner influences how values are transformed upon retrieval.
Simple Code Example - Lowercasetype LowercaseString string
// Implements driver.Valuer. func (ls LowercaseString) Value() (driver.Value, error) { return driver.Value(strings.ToLower(string(ls))), nil }
// Implements sql.Scanner. Simplistic -- only handles string and []byte func (ls *LowercaseString) Scan(src interface{}) error { var source string switch src.(type) { case string: source = src.(string) case []byte: source = string(src.([]byte)) default: return errors.New("Incompatible type for LowercaseString") } *ls = LowercaseString(strings.ToLower(source)) return nil }
Example, Cont’d: Inserting Values
// Insert a row that's not lowercased, and one that is. var normalString string = "I AM UPPERCASED NORMAL STRING" var lcString LowercaseString = "I AM UPPERCASED MAGIC STRING"
_, err = db.Exec("INSERT INTO test.hello VALUES(?), (?)", normalString, lcString) if err != nil { log.Fatal(err) }
• Result: The database will contain"I AM UPPERCASED NORMAL STRING" and"i am uppercased magic string"
Example, Cont’d: Selecting Values rows, err := db.Query("SELECT * FROM test.hello") if err != nil { log.Fatal(err) } defer rows.Close() for rows.Next() { var s1 LowercaseString err = rows.Scan(&s1) if err != nil { log.Print(err) } log.Print(s1) }
• Result: the app will log"i am uppercased normal string"and"i am uppercased magic string"
Example Source Code
• Please see Go+Database ebook for full source code and downloadable link, plus in-depth explanation: vividcortex.com/resources/building-database-driven-apps-with-go/
Extending the Example To Encryption• Use the standard crypto/aes library in Go’s stdlib
• Managing “secret” is an exercise for the reader!
• See https://vividcortex.com/blog/2014/11/11/encrypting-data-in-mysql-with-go/
block, err := aes.NewCipher(secret) if err != nil { return nil, err } ciphertext := make([]byte, aes.BlockSize+len(buf)) if _, err := io.ReadFull(rand.Reader, ciphertext[:aes.BlockSize]); err != nil { return nil, err } stream := cipher.NewCFBEncrypter(block, ciphertext[:aes.BlockSize]) stream.XORKeyStream(ciphertext[aes.BlockSize:], buf)
Extending To Additional Services (e.g. VividCortex’s Architecture, Vastly Over-Simplified)
Agents
Public API
Internal Service
Encryption BoundaryKMS
More Resources
Credits
• Lock https://www.flickr.com/photos/photosightfaces/8152791780/
• Agenda https://www.flickr.com/photos/puntodevista/639615047/
• Lock icon http://icons.iconarchive.com/icons/artua/mac/512/Lock-icon.png
• User icon simpleicons.com
• Key icon iconarchive.com
• Safe icon softicons.com