【问题标题】:How to encrypt Spring Boot application data in mongodb如何在 mongodb 中加密 Spring Boot 应用程序数据
【发布时间】:2020-04-08 10:11:01
【问题描述】:

我有一个在数据库中存储支付信息的 Spring Boot 应用程序。应用程序有端点

  • GET /api/orders - 通过过滤器获取订单
  • POST /api/orders - 添加新订单
  • PUT /api/orders - 更新订单
  • DELETE /api/orders - 删除订单

这些端点本身并不安全,我不想在应用程序级别保护它们。来自用户的所有流量都转到 HTTPS 代理,该代理将对其进行解密并转发给应用程序。

但是,我使用 mongo atlas 免费版进行原型设计 https://www.mongodb.com/cloud/atlas/faq

我放入数据库的所有数据都必须加密。甚至文档结构(字段名称和类型)也必须加密。

How to encrypt a field 对我不起作用,因为我想加密整个文档。 我不想使用像下面这样的非官方库(因此没有人保证库是否安全)

<dependency>
   <groupId>com.bol</groupId>
   <artifactId>spring-data-mongodb-encrypt</artifactId>
   <version>1.3.0</version>
</dependency>

我想到的一个想法是将应用程序配置为使用密码(以某种方式在给定时间配置或生成)。

/**
* Provides a password to encrypt a document.
**/
// TODO  How to do it better? I still have to improve it.
@Component
public class PasswordProviderImpl implements PasswordProvider {
    
    private static final byte[] MASTER_PASSWORD = {1, 11, 37, 166, 11, 77};

    @Autowired
    private Environment environment;

    // I do not care about the implementation yet
    public char [] getPassword() {
        final byte[] envPassword = environment.getProperty("appplicationPassword").toString().toByteArray();
        return envPassword;
    }
}
/**
* Encrypts input byte array with provided password, afterwards, cleans input data and password - populates them with zeros - 0.
**/
@Component
public class Encryptor {
    private PasswordProvider passwordProvider;

    public byte [] encrypt(final byte unecrypted) {
        final byte [] password = passwordProvider.getPassword();
        final byte [] encrypted = xor(unecrypted, password);
        makeZeros(password);
        makeZeros(unecrypted);
        return encrypted;
    }
    
    private void makeZeros(final byte[] array) { /*Implementation*/}
    private byte[] xor(final byte [] arg1, final byte[] arg2) {/*Implementation*/}
}
/**
* Represents a unit of data in my application. Its values and fields and structure - everything should be encrypted.
**/
public class Order {
    private ObjectId id;
    private Instant createdDate;
    private Instant updatedDate;
    private Money amount;
    private String additionalDetails;

    // gettters, setters, constructor
}

转换器,找到Set MongoDb converter programmatically

/**
* It is declared application configuration. It defines how to store {@link Order} in mongodb
**/
@Component
public OrderConverter implements onverter<Order, SecuredOrder> {
    
    private ObjectMapper objectMapper;
    private Encryptor encryptor;
    private Base64Converter base64Converter;

    @Override 
    public SecuredOrder convert(Order source) { 
        final String json = objectMapper.writeValueAsString(source);
        final unencrypted = json.toByteArray();
        final byte[] encrypted = encryptor.encrypt(unencrypted);
        final String payload = base64Converter.toBase64(encrypted);
        return SecuredOrder.of(order.getId(), payload);
    }
}
public class SecuredOrder {
    private ObjectId id; // same as in order id
    private String encryptedPayload; // The converter will make it
}

@Service
public OrderService {
    public void saveOrder(Order order) {
        orderRepository.save(order);
    }
}

如果你做过类似的事情,请给我一个方向。我真的很想把它做好。

另外,mongodb提供了加密机制,或许我应该使用它?

https://docs.mongodb.com/manual/core/security-encryption-at-rest/

https://docs.mongodb.com/manual/core/security-encryption-at-rest/#encrypted-storage-engine

【问题讨论】:

  • 你说'因此没有人保证图书馆是否安全',然后从互联网上复制随机代码 sn-ps ......顺便说一句,spring-data-mongodb-encrypt 库完全符合你的要求想要,您只需将数据放在子文档中并使用 @Encrypted 标记该字段,但您是否更喜欢自制解决方案而不是开源解决方案。
  • 好的,我对图书馆组 id bol 感到困惑(我以前不知道那家公司)。我怎么知道谁来维护图书馆?我认为这是一家开源了他们的一些解决方案的公司。并且公司是知名的并且会关心他们的声誉。

标签: java mongodb spring-boot encryption


【解决方案1】:

如果您能够使用 WiredTiger 存储引擎并且您使用的是 MongoDB 3.2 或更高版本,则可以使用它的 Encryption at Rest 功能(正如您在帖子底部提到的!),但请注意这是可用的仅适用于企业版。

【讨论】:

    猜你喜欢
    • 2021-12-07
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-10
    • 1970-01-01
    • 2019-11-14
    • 2019-09-30
    相关资源
    最近更新 更多