Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
Upcoming SlideShare
What to Upload to SlideShare
What to Upload to SlideShare
Loading in …3
×
1 of 128

MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2

3

Share

Download to read offline

Encryption is not a new concept to MongoDB. Encryption may occur in-transit (with TLS) and at-rest (with the encrypted storage engine). But MongoDB 4.2 introduces support for Client Side Encryption, ensuring the most sensitive data is encrypted before ever leaving the client application. Even full access to your MongoDB servers is not enough to decrypt this data. And better yet, Client Side Encryption can be enabled at the "flick of a switch".

This session covers using Client Side Encryption in your applications. This includes the necessary setup, how to encrypt data without sacrificing queryability, and what trade-offs to expect.

Related Books

Free with a 30 day trial from Scribd

See all

Related Audiobooks

Free with a 30 day trial from Scribd

See all

MongoDB .local San Francisco 2020: Using Client Side Encryption in MongoDB 4.2

  1. 1. Introducing…
  2. 2. db.coll.insert({ _id: 1, name: "Doris", ssn: "457-55-5462" })
  3. 3. doc = db.coll.find_one({ ssn: "457-55-5462" })
  4. 4. print (doc)
  5. 5. { _id: 1 name: "Doris", ssn: "457-55-5462" }
  6. 6. db.coll.insert({ name: "Doris", ssn: "457-55-5462" }) { insert: "coll", documents: [{ name: "Doris", ssn: BinData(6, "a10x…") }] } You see: MongoDB sees: Encrypt before sending
  7. 7. { _id: 1 name: "Doris", ssn: BinData(6, "a10x…") } Driver receives: You see: { _id: 1 name: "Doris", ssn: "457-55-5462" } Decrypt after receiving
  8. 8. How does this differ from…? •… encryption in-transit (TLS) •… encryption at-rest (encrypted storage engine)
  9. 9. Attacker query App (Client) Disk insert write MongoDB Auth db.coll.insert({ name: "Doris", ssn: "457-55-5462" })
  10. 10. Disk insert write MongoDB Attacker snoop TLS db.coll.insert({ name: "Doris", ssn: "457-55-5462" }) App (Client)
  11. 11. Disk insert write MongoDB Attacker insert TLS db.coll.insert({ name: "Doris", ssn: "457-55-5462" }) App (Client)
  12. 12. Disk insert write MongoDB Attacker steal ESE db.coll.insert({ name: "Doris", ssn: "457-55-5462" }) App (Client)
  13. 13. Disk insert write MongoDB Attacker login Client Side Encryption db.coll.insert({ name: "Doris", ssn: "457-55-5462" }) App (Client)
  14. 14. Disk insert write MongoDB Boundaries of unencrypted data App (Client)
  15. 15. Disk insert write MongoDB … with Encrypted Storage Engine App (Client)
  16. 16. Disk insert write MongoDB … and TLS App (Client)
  17. 17. Disk insert write MongoDB with Client Side Encryption App (Client)
  18. 18. Disk insert write MongoDB ssn: BinData(6, "a10x…") App (Client)
  19. 19. db.coll.update({}, { $set: { ssn: "457-55-5462" } }) { update: "coll", updates: [{ q:{}, u: { $set: { ssn: BinData(6, "a10x…") } } }] } You see: MongoDB sees: Update that overwrites value
  20. 20. db.coll.aggregate([{ $project: { name_ssn: {$concat: [ "$name", " - ", "$ssn" ] } } }] Aggregate acting on the data
  21. 21. Find with equality query * For deterministic encryption db.coll.find({ssn: "457-55-5462" }) { find: "coll", filter: { ssn: BinData(6, "a10x…") } } You see: MongoDB sees:
  22. 22. Find with equality query * For deterministic encryption db.test.find( { $and: [ { $or: [ { ssn : { $in : [ "457-55-5462", "153-96-2097" ]} }, { ssn: { $exists: false } } ] }, { name: "Doris" } ] } ) You see:
  23. 23. Find with equality query * For deterministic encryption MongoDB sees: { find: "coll", filter: { $and: [ { $or: [ { ssn : { $in : [ BinData(6, "a10x…"), BinData(6, "8dk1…") ]} }, { ssn: { $exists: false } } ] }, { name: "Doris" } ] } }
  24. 24. MongoDB Attacker Login
  25. 25. Destroy the key Provably delete all user data. GDPR "right-to-be-forgotten"
  26. 26. Doris Private stuff in storage
  27. 27. PoliceDoris Private stuff in storage
  28. 28. Vault key Held only by you Vault
  29. 29. Encrypted Data MongoDB Encryption Key
  30. 30. { _id: 1, ssn: BinData(0, "A81…"), name: "Kevin" } { _id: 2, ssn: BinData(0, "017…"), name: "Eric" } { _id: 3, ssn: BinData(0, "5E1…"), name: "Albert" } …
  31. 31. client = MongoClient( auto_encryption_opts=opts)
  32. 32. Not sensitive {
  33. 33. One key for all vaults
  34. 34. One key per vault
  35. 35. { name: "Doris" ssn: "457-55-5462", email: "Doris@gmail.com", credit_card: "4690-6950-9373-8791", comments: [ …. ], avatar: BinData(0, "0fi8…"), profile: { likes: {…}, dislikes: {…} } }
  36. 36. Describes JSON { bsonType: "object", properties: { a: { bsonType: "int" maximum: 10 } b: { bsonType: "string" } }, required: ["a", "b"] } { a: 5, b: "hi" } { a: 11, b: false } JSON Schema
  37. 37. { bsonType: "object", properties: { ssn: { encrypt: { … } } }, required: ["ssn"] } JSON Schema "encrypt"
  38. 38. encrypt: { keyId: (…), algorithm: (…), bsonType: (…) } bsonType indicates the type of underlying data. algorithm indicates how to encrypt (Random or Deterministic). keyId indicates the key used to encrypt.
  39. 39. opts = AutoEncryptionOptions( schema_map = { "db.coll": <schema> } …)
  40. 40. Remote Schema Fallback db.createCollection("coll", { validator: { $jsonSchema: … } } ) Misconfigured Client insert "457-55-5462" error, that should be encrypted MongoDB
  41. 41. What if … the server lies about the schema? Misconfigured Client insert "457-55-5462" Evil MongoDB ok :)
  42. 42. schema_map Sub-options
  43. 43. Key vault Key vault key Held only by you
  44. 44. Stores encrypted keys
  45. 45. opts = AutoEncryptionOptions( schema_map = { "db.coll": <schema> }, key_vault_namespace = "db.keyvault" …)
  46. 46. schema_map Sub-options key_vault_namespace
  47. 47. What if … attacker drops key vault collection?
  48. 48. Keep at home opts = AutoEncryptionOptions( schema_map = { "db.coll": <schema> }, key_vault_namespace = "db.keyvault", key_vault_client = <client> …)
  49. 49. schema_map Sub-options key_vault_namespace key_vault_client
  50. 50. (Key Management Service)
  51. 51. Protects keys Stores keys KMS Key vault key Key vault Key vault collection
  52. 52. Decryption requires
  53. 53. opts = AutoEncryptionOptions( schema_map = { "db.coll": <schema> }, key_vault_namespace = "db.keys", kms_providers = <creds> …)
  54. 54. schema_map Sub-options key_vault_namespace key_vault_client kms_providers
  55. 55. db.coll.insert({ name: "Doris", ssn: "457-55-5462" }) Get encrypted key Decrypt the key with KMSDecrypt the key with KMS Encrypt 457-55-5462 Send insert Compare to JSON schema
  56. 56. You need… •MongoDB 4.2 server •Beta client (shell, Java, Python, NodeJS, Go, C#) •Enterprise license for auto encryption •Community for explicit encryption
  57. 57. *
  58. 58. Authenticated Encryption with Associated Data using the Advance
  59. 59. AEAD_AES_256_CBC_HMAC_SHA_512 Provides confidentiality + integrity
  60. 60. AEAD_AES_256_CBC_HMAC_SHA_512-Deterministic AEAD_AES_256_CBC_HMAC_SHA_512-Random
  61. 61. coll.insert({ ssn: "457-55-5462" }) { ssn: BinData(6, "a10x…") } You see: MongoDB stores: coll.insert({ ssn: "457-55-5462" }) { ssn: BinData(6, "f991…") } …Random
  62. 62. coll.insert({ ssn: "457-55-5462" }) { ssn: BinData(6, "a10x…") } You see: MongoDB stores: coll.insert({ ssn: "457-55-5462" }) { ssn: BinData(6, "a10x…") } …Deterministic
  63. 63. Can be queried doc = db.coll.find({ ssn: "457-55-5642" }) …Deterministic
  64. 64. Only for binary comparable types. db.coll.find({ a: NumberDecimal("1.2")}) { a: NumberDecimal("1.2") } { a: NumberDecimal("1.20") } MongoDB returns: …Deterministic
  65. 65. { a: BinData(6, "b515…") } { a: BinData(6, "801f…") } Encrypted as: { a: NumberDecimal("1.2") } { a: NumberDecimal("1.20") } Value:
  66. 66. db.coll.find({ a: NumberDecimal("1.2") }) { a: NumberDecimal("1.2") } MongoDB returns: "a" encrypted
  67. 67. Encrypt-able values Deterministic encryption valid for… •String •Binary •ObjectID •Date •Regex •DBPointer •Javascript •Symbol •Int •Timestamp •Long Random encryption valid for… •(all of deterministic) •Document •Array •JavascriptWithScope •Double •Decimal128 •Bool
  68. 68. { ssn: BinData(6, "AWNkTYTCw89Ss1DPzV3/2pSRDNGNJ9NB" } New binary subtype Older drivers and older MongoDB will treat as a black box.
  69. 69. byte algorithm byte[16] key_id byte original_bson_type byte* payload Ciphertext
  70. 70. byte algorithm byte[16] key_id byte original_bson_type byte* payload key_id + algorithm describes how to decrypt. No JSON Schema necessary! Ciphertext
  71. 71. byte algorithm byte[16] key_id byte original_bson_type byte* payload Provides extra server-side validation. But prohibits single-value types (MinKey, MaxKey, Undefined, Null) Ciphertext
  72. 72. byte algorithm byte[16] key_id byte original_bson_type byte* payload Payload includes encoded IV and padding block, and HMAC. Ciphertext adds between 66 to 82 bytes of overhead. Ciphertext
  73. 73. ce = ClientEncryption(opts) encrypted = ce.encrypt("457-55-5462", opts)) decrypted = ce.decrypt(BinData(6, "a10x…"))) id = ce.createDataKey(opts)
  74. 74. db.test.find({ $or: [ { ssn : { $in : [ "457-55-5462", "153-96-2097" ]} }, { name: "Doris" } ] }) db.test.find({ $or: [ { ssn : { $in : [ BinData(6, "a10x…"), BinData(6, "8dk1…") ]} }, { name: "Doris" } ] })
  75. 75. Limitations If we cannot parse… or it is impossible… we err for safety.
  76. 76. { passport_num: "281-301-348", ssn: "457-55-5462" } { passport_num: "390-491-482", ssn: "482-38-5899" } { passport_num: "104-201-596" } passport_num and ssn encrypted with different keys
  77. 77. db.test.aggregate([ ]) { $project: { identifier: { $ifNull: ["$ssn", "$passport_num" ] } } }, { $match: { identifier: "457-55-5462" } } How do we encrypt 457-55-5462?
  78. 78. opts = AutoEncryptionOptions( bypass_auto_encryption = True …) client = MongoClient(auto_encryption_opts=opts) (Decryption still occurs)
  79. 79. ce = ClientEncryption(opts) db.test.aggregate([ ]) { $project: { identifier: { $ifNull: ["$ssn", "$passport_num" ] } } }, { $match: { identifier: ce.encrypt("457-55-5462", opts) } }
  80. 80. One key ce = ClientEncryption(opts) id = ce.createDataKey(keyopts) Create with ClientEncryption
  81. 81. One key Specify with JSONSchema … ssn: { encrypt: { keyId: [id], algorithm: (…), bsonType: (…) } }
  82. 82. One key db.coll.insert({ name: "Doris", ssn: "457-55-5462" }) Query key vault by _id Compare to JSON schema
  83. 83. Labeled keys ce = ClientEncryption(opts) id = ce.createDataKey(keyopts, keyAltNames=["Doris"]) Create with ClientEncryption
  84. 84. Labeled keys Specify JSON Pointer with JSONSchema … ssn: { encrypt: { keyId: "/name", algorithm: (…), bsonType: (…) } }
  85. 85. db.coll.insert({ name: "Doris", ssn: "457-55-5462" }) Query key vault by label "Doris" Compare to JSON schema Labeled keys
  86. 86. db.coll.insert({ name: "Kevin", ssn: "457-55-5462" }) Query key vault by label "Kevin" Compare to JSON schema Labeled keys
  87. 87. DorisDB MongoDB Cloud Hosting - By Doris ™
  88. 88. App Server User insert MongoDB (Key Vault) fetch key decrypt key DorisDB (Storage) encrypted insert
  89. 89. { email: (encrypted), pwd: (encrypted) } Email deterministic, pwd random, uses collection key
  90. 90. { user_id: "…", title: (encrypted), body: (encrypted) } Encrypted randomly with per-user key
  91. 91. User MongoDB (Key Vault) delete user key DorisDB (Storage) delete all posts App Server "Delete my data" … but was it really deleted?
  92. 92. Users :) Latency :(
  93. 93. EAST DICTATORLAND Global Shards
  94. 94. EAST DICTATORLAND
  95. 95. EAST DICTATORLAND { _id: 1, body: BinData(6, "A81…") } { _id: 2, body: BinData(6, "017…") } { _id: 3, body: BinData(6, "5E1…") } …

×