2017-05-29 97 views
1

後不叫我有一個貓鼬的架構以「貓鼬加密」的插件,例如:貓鼬加密中間件聚集

let someSchema = new Schema({name, age}); 

someSchema.plugin(mongoose-encryption, { 
     encryptionKey: 'eKey', 
     signingKey: 'sKey', 
     encryptedFields: ['age'], 
     decryptPostSave: false 
    }); 

啓動模式,我試圖聚集一些查詢庫後:

let aggregation = []; // just return all the docs. 
someModel.aggregate(aggregation, (err, persons) => { 
     return persons; 
}); 

結果我仍然得到加密的年齡字段,很少閱讀已經透露,「初始化」事件的「後」的方法聚集後,不叫(這裏解釋 - Mongoose Middleware Docs)。

有沒有很好的解決方案?或任何其他解決方法?

  • 該數據必須加密。

  • 聚集還需要(在現實生活中 - 查找到其他集合)

回答

1

由於我沒有找到一個更好的答案,我改變了我的代碼(如解決辦法不幸)解密對象由我自己 - 在聚合完成後使用mongoose加密的代碼進行解密。

大部分的代碼是從GitHub(在我的代碼稱爲decryptOne)採取: decryptSync function of mongoose-encryption

的「棘手」的事情就是解密內查找值 - 內部文件也有「_ct」字段應該解密。

let lookup: { [innerField: string]: string[]; } = { 
        user: ['bio'] 
       }; 
this.decryptAggregation(aggregationResult, lookup); 

我的函數獲取解密後已知查找集合及其所需字段的字典。在這個例子中,名爲用戶的其他集合及其加密字段就是他的生物。

decryptAggregation(res: any[], innerLookup: { [innerField: string]: string[]; }) { 
    for (let doc of res) { 
     this.decryptSync(doc, innerLookup); 
    } 
} 

private decryptSync(doc: any, innerLookup: { [innerField: string]: string[]; }) { 
    this.decryptOne(doc, this.encryptedFields); 
    for (let innerObj in innerLookup) { 
     if (innerLookup.hasOwnProperty(innerObj)) { 
      this.decryptOne(doc[innerObj], innerLookup[innerObj]); 
     } 
    } 
}; 

private decryptOne(doc: any, fields: string[]) { 
    let ct, ctWithIV, decipher, iv, idString, decryptedObject, decryptedObjectJSON, decipheredVal; 

    if (doc._ct) { 
     ctWithIV = doc._ct.hasOwnProperty('buffer') ? doc._ct.buffer : doc._ct; 
     iv = ctWithIV.slice(this.VERSION_LENGTH, this.VERSION_LENGTH + this.IV_LENGTH); 
     ct = ctWithIV.slice(this.VERSION_LENGTH + this.IV_LENGTH, ctWithIV.length); 

     decipher = crypto.createDecipheriv(this.ENCRYPTION_ALGORITHM, this.encryptionKey, iv); 
     try { 
      decryptedObjectJSON = decipher.update(ct, undefined, 'utf8') + decipher.final('utf8'); 
      decryptedObject = JSON.parse(decryptedObjectJSON); 
     } catch (err) { 
      if (doc._id) { 
       idString = doc._id.toString(); 
      } else { 
       idString = 'unknown'; 
      } 
      throw new Error('Error parsing JSON during decrypt of ' + idString + ': ' + err); 
     } 

     fields.forEach((field) => { 
      decipheredVal = mpath.get(field, decryptedObject); 

      //JSON.parse returns {type: "Buffer", data: Buffer} for Buffers 
      //https://nodejs.org/api/buffer.html#buffer_buf_tojson 
      if (_.isObject(decipheredVal) && decipheredVal.type === "Buffer") { 
       this.setFieldValue(doc, field, decipheredVal.data); 
      } else { 
       this.setFieldValue(doc, field, decipheredVal); 
      } 
     }); 

     doc._ct = undefined; 
     doc._ac = undefined; 
    } 
} 

那些我得到了我想要的目標函數完全解密後,做的最後一件事是投影想字段返回給客戶端 - 與lodash.pick