如何在确保结果确定性的同时使用充气城堡加密数据

How to encrypt data with bouncy castle while ensuring the result is deterministic

问题

我们想加密个人身份信息。它们不应该是可读的。但是,由于结果也将用于机器学习,因此每次对一个值(例如 "ABC")进行加密时,生成的数据应该是相同的。

大多数加密密码都包含 initialization vector。这违背了我们的需要。需要明确的是,数据应该是加密的,但这并不需要是防弹的。数据永远不会传输到组织外部,这样做只是为了遵守 GDPR。

上下文

我们决定使用 bouncy castle,因为它支持大量加密模式,包括(显然速度很快的 ECC)。由于我们谈论的是每天加密数 TB,因此性能良好会很好。

解决问题

虽然 bouncy castle 库写得很好,但似乎很难找到好的文档和使用示例。我正在努力寻找我的切入点。我是否必须查看 org.bouncycastle.cryptoorg.bouncycastle.crypto.engines 包?还是 crypto.ec?我找到了 ZeroBytePadding class,我相信它应该指向一个潜在的引擎,它可以做我想做的事,但我找不到我要找的东西。

目标

A class 有一组类似于此的方法:

class Anonomyzer{
  def initialize(publicKey: String, privateKey: String): Unit
  def encode(data: Array[Byte]): Array[Byte]
  def decode(data: Array[Byte]): Array[Byte]
}

下面的代码应该是正确的

Anonomyzer.initialize("PUBLIC", "PRIVATE")
val once = Anonomyzer.encode(data)
val twice = Anonomyzer.encode(data)
Arrays.equals(once, twice)

编辑: 我已经阅读了更多关于这个的内容,发现我正在寻找的东西叫做 Electronic Codebook 操作模式。虽然这不是完全安全的,但这是我们对 AFAIK 的最大希望。

However, because the results will also be used for machine learning, each time a value (say "ABC") gets encrypted, the resulting data should be the same

您可能有更多选择。在需要加密的地方正确加密数据仍然更安全。您可能有不同的数据集用于不同的目的。

只是建议:

  • 你可以匿名化学习数据集,剥离他们的 PII 数据并将它们聚合到合理的水平,这对 ML 仍然有价值。我更喜欢这个选项,因为它很干净,不会有违反任何规则或泄露受保护信息的风险
  • 您可以对 PII(或分类数据)进行哈希处理,这将提供唯一映射而无需可逆映射(尽管始终会从原始值进行映射)
  • 对于定量数据,您可以搜索 "order preserving encryption" 这可能不是微不足道的(这就是我选择第一个选项的原因之一)

走捷径(使用 ECB 或静态 IV)在某些情况下可能会完全破坏加密数据的安全性。所以在你真正知道自己在做什么之前,你可能会开枪打自己的腿

We have decided to use bouncy castle because it supports a large number of encryption modes, including the (apparently fast ECC)

我会说 - 你不需要 BC 图书馆。这是一个写得很好的库,但在你的情况下,我没有看到任何特定的需求。

apparently fast ECC). Since we are talking about encrypting several TB a day, it would be nice to have good performance

ECC仍然是非对称加密,通常用于混合加密(加密对称数据加密密钥)。因此,如果您的目标是速度,您可以使用检查您的 JVM 和 VM 是否允许本机 AES-NI 支持或使用一些快速密码(salsa,..)。如果处理得当,加密通常不是性能瓶颈

I am struggling to find my entrypoint.

在大多数情况下,您可以使用默认的 Java 加密 API 和指定的提供商

Security.addProvider(new BouncyCastleProvider());
... 
 Cipher cipher = Cipher.getInstance("AES/OFB/NoPadding", "BC");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");

编辑:固定填充组合