MongoDB如何字段級加密儲存和查詢

MongoDB4.2企業版引入了字段級別加密 詳情

MongoDB的手冊說字段級加密的自動功能僅在MongoDB 4.2 Enterprise和MongoDB Atlas 4.2集羣中可用。詳情

既然不能使用4.2的字段級別加密,那就換種方式,引入插件!mongoose-field-encryption

 

環境要求:

  • Node >=6 (Use 2.3.4 for Node >=4.4.7 && <=6.x.x)
  • MongoDB >=2.6.10
  • Mongoose >=4.0.0

以egg.js爲例

一、安裝插件

npm install mongoose-field-encryption --save-exact

二、使用

app/model/message.js

module.exports = app => {
  const mongoose = app.mongoose
  const Schema = mongoose.Schema;
  const mongooseFieldEncryption = require("mongoose-field-encryption").fieldEncryption;
  const messageSchema = new Schema({
    title: String,
    message: String,
    phone: String
  });

  messageSchema.plugin(mongooseFieldEncryption, {
    fields: ["message", "phone"],
    secret: "liubao",
    saltGenerator: function (secret) {
      return "1234567890123456"; //理想情況下,應使用該機密返回長度爲16的字符串
    }
  });
  return mongoose.model('message', messageSchema)
}

app/model/post.js

module.exports = app => {
  const mongoose = app.mongoose
  const mongooseFieldEncryption = require("mongoose-field-encryption").fieldEncryption;
  const Schema = mongoose.Schema;
  const PostSchema = new Schema({
    title: String,
    message: String,
    references: {
      author: String,
      date: Date
    }
  });
  PostSchema.plugin(mongooseFieldEncryption, {fields: ["message", "references"], secret: "liubao"})
  return mongoose.model('post', PostSchema)
}

app/controller/test.js

const Controller = require('egg').Controller;

class TestController extends Controller {
  async test() {
    const {ctx} = this;
    const messageModel = this.app.mongoose.model('message')
    const postModel = this.app.mongoose.model('post')

    const post = new postModel({title: "some text", message: "hello all"});
    post.save(function (err) {
      console.log(post.title); //一些文本(僅通過選項將消息字段設置爲加密)
      console.log(post.message); // a9ad74603a91a2e97a803a367ab4e04d:93c64bf4c279d282deeaf738fabebe89
      console.log(post.__enc_message); // true
    });


    const title = "測試標題";
    const phone = "15900000000";
    const message = "hello all";
    const messageToSave = new messageModel({title, message, phone});
    await messageToSave.save();

// note that we are only providing the field we would like to search with
    const messageToSearchWith = new messageModel({phone});
    messageToSearchWith.encryptFieldsSync();

// `messageToSearchWith.name` contains the encrypted string text
    const results = await messageModel.find({phone: messageToSearchWith.phone});
    ctx.body = results

  }
}

module.exports = TestController;

模擬請求: 

結果:

 

結果成功!

 

 非egg.js框架的話可以參考如下自行修改,效果一樣

const Controller = require('egg').Controller;
const mongoose = require("mongoose");
const mongooseFieldEncryption = require("mongoose-field-encryption").fieldEncryption;
const Schema = mongoose.Schema;
const PostSchema = new Schema({
  title: String,
  message: String,
  references: {
    author: String,
    date: Date
  }
});
PostSchema.plugin(mongooseFieldEncryption, {fields: ["message", "references"], secret: "liubao"})

const messageSchema = new Schema({
  title: String,
  message: String,
  name: String
});

messageSchema.plugin(mongooseFieldEncryption, {
  fields: ["message", "phone"],
  secret: "liubao",
  saltGenerator: function (secret) {
    return "1234567890123456"; //理想情況下,應使用該機密返回長度爲16的字符串
  }
});

class TestController extends Controller {
  async test() {
    const { ctx } = this;

    const Post = mongoose.model("Post", PostSchema);
    
    const post = new Post({ title: "some text", message: "hello all" });
    
    post.save(function(err) {
        console.log(post.title); //一些文本(僅通過選項將消息字段設置爲加密)
        console.log(post.message);
        console.log(post.__enc_message); // true
    });


    const title = "some text";
    const phone = "15900000000";
    const message = "hello all";

    const Message = mongoose.model("Message", messageSchema);

    const messageToSave = new Message({title, message, phone});
    await messageToSave.save();

// note that we are only providing the field we would like to search with
    const messageToSearchWith = new Message({phone});
    messageToSearchWith.encryptFieldsSync();

// `messageToSearchWith.name` contains the encrypted string text
    const results = await Message.find({phone: messageToSearchWith.phone});
    ctx.body = results

  }
}

module.exports = TestController;

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章