【发布时间】: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