Java 如何使用bouncy castle加密数据,同时确保结果具有确定性

Java 如何使用bouncy castle加密数据,同时确保结果具有确定性,java,scala,encryption,bouncycastle,Java,Scala,Encryption,Bouncycastle,问题 我们想加密个人身份信息。它们不应该是可读的。但是,由于结果也将用于机器学习,因此每次对值(如“ABC”)进行加密时,生成的数据应该是相同的 大多数加密密码都包含一个。这与我们的需要背道而驰。要明确的是,数据应该加密,但这不需要防弹。数据永远不会传输到组织外部,这样做只是为了遵守GDPR 上下文 我们决定使用它,因为它支持大量加密模式,包括(显然是快速ECC)。因为我们说的是每天加密几TB,所以拥有良好的性能会很好 解决方案问题 尽管bouncy castle库写得很好,但似乎很难找到好的文

问题

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

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

上下文

我们决定使用它,因为它支持大量加密模式,包括(显然是快速ECC)。因为我们说的是每天加密几TB,所以拥有良好的性能会很好

解决方案问题

尽管bouncy castle库写得很好,但似乎很难找到好的文档和使用示例。我正在努力寻找我的入口点。我是否必须查看
org.bouncycastle.crypto
,或
org.bouncycastle.crypto.engines
包?还是
crypto.ec
?我找到了
ZeroBytePadding
类,我相信该类可以为我指明一个潜在的引擎,它可以实现我想要的功能,但我找不到我想要的

目标

具有一组类似于以下内容的方法的类:

class Anonomyzer{
  def initialize(publicKey: String, privateKey: String): Unit
  def encode(data: Array[Byte]): Array[Byte]
  def decode(data: Array[Byte]): Array[Byte]
}
以下代码应为true

Anonomyzer.initialize("PUBLIC", "PRIVATE")
val once = Anonomyzer.encode(data)
val twice = Anonomyzer.encode(data)
Arrays.equals(once, twice)
编辑: 我读了更多关于这方面的内容,发现我正在寻找的是 运作模式。虽然这并不完全安全,但这是我们对AFAIK的最好希望

但是,由于结果也将用于机器学习,因此每次对值(如“ABC”)进行加密时,结果数据应相同

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

只是建议:

  • 您可以匿名化学习数据集,从PII中剥离数据并将其聚合到合理的水平,这对ML来说仍然是有价值的。我更喜欢这个选项,因为这样它是干净的,不会违反任何规则或泄露受保护的信息
  • 您可以散列PII(或分类数据),这将提供唯一的映射,而无需可逆映射(尽管始终存在来自原始值的映射)
  • 对于定量数据,您可以搜索“保序加密”,这可能不是一个简单的正确操作(这就是我选择第一个选项的原因之一)
在某些情况下,使用快捷方式(使用ECB或静态IV)可能会完全破坏加密数据的安全性。所以,在你真正知道自己在做什么之前,你可能会朝自己的腿开枪

我们决定使用bouncy castle,因为它支持大量加密模式,包括(显然是快速ECC)

我想说,你不需要BC图书馆。这是一个写得很好的库,但在你的情况下,我看不出有任何具体的需要

显然很快(ECC)。因为我们说的是每天加密几TB,所以拥有良好的性能会很好

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

我正在努力寻找我的入口点

在大多数情况下,您可以对指定的提供程序使用默认Java crypto API

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


编辑:固定填充组合

您的要求相互冲突,而且您似乎不理解对称加密和非对称加密之间的区别。加密不一定等同于安全,将相同的明文加密为相同的密文是一个安全问题。它们实际上不是我的要求,而是我们客户的要求。如果你能帮助我,我很乐意把这个答案改成“正确”。我认为,这种用例相当常见:加密个人数据,但仍然要确保例如电话号码在输出上产生相同的字符串。我知道潜在的彩虹攻击。你不需要使用像bouncy castle这样的安全库进行“加密”。只需从个人数据计算一个散列,它是不可逆和确定的-不使用初始化向量。好吧,我们确实需要反转数据。不幸的是,一旦导出的模型被计算出来,预测的客户信息就会被输入邮件活动等,因此数据需要解密。我希望它是不同的。但这正是客户要求的,如果我可以问的话,您为什么选择PKCS5P添加?@pascalwhoop您是对的,OFB不需要任何填充(已修复)。不管怎样,重要的是-要使用BouncyCastle,最简单的选择就是使用带有provider参数的默认Java API。但是对于常用的BC不会给你任何好处(相反,我不确定BC是否支持AES-NI,需要检查,它不像2年前)
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "BC");