Java 基于用户输入密钥的加密
上下文:多租户应用程序 功能:敏感数据加密 故事: 作为租户的管理员,我希望使用我自己的密码或密码对敏感数据进行加密,以便我,而且只有我能够完全控制使用的密钥 验收标准:Java 基于用户输入密钥的加密,java,encryption,password-protection,password-encryption,Java,Encryption,Password Protection,Password Encryption,上下文:多租户应用程序 功能:敏感数据加密 故事: 作为租户的管理员,我希望使用我自己的密码或密码对敏感数据进行加密,以便我,而且只有我能够完全控制使用的密钥 验收标准: 每个租户的管理员应该能够定义用于加密的密码或密码短语 只有提供原始密码或密码短语的租户管理员才应该知道密钥 一旦租户管理员提供了密码或密码短语,就应该将其安全存储 我的问题 到目前为止,我们一直在使用对称密钥加密,并在应用程序中硬编码应用程序范围的密钥。如果每个租户都想使用自己的密钥,那么这将不再起作用。我们如何让每个用户定义
在不知道密钥的情况下不可能加密/解密。否则,PBE使用密钥派生函数(PBKDF2)似乎是一个明确的例子。您可以使用非对称加密,但它只会在您的用例中的加密过程中保护私钥。下面是一段代码,展示了如何在您的应用程序中使用基于密码的加密(PBE),摘自:
应用程序提示输入的密码(或密码短语)不是选项吗?当你说“我和只有我”时,你的意思是即使你的服务也不会解密数据吗?也就是说,它只是将加密的块返回给用户,然后在客户端对其进行解密(如某些在线备份服务)?或者你的意思是你的应用程序仍然像现在一样运行,用户在客户端上无需额外的努力/配置就能看到他们的数据,但幕后租户1的数据使用与租户2不同的密钥加密?首先你说“管理员应该能够定义密钥”和“只有管理员应该知道密钥”;然后“我们如何让每个用户定义他们自己的密钥?”。这些似乎是不相容的。我遗漏了什么?@ckhan系统应该能够根据用户输入的密码对数据进行加密和解密。是的,幕后租户1的数据应该使用不同于租户2的密钥进行加密。但每个租户的密钥应安全存储,以便只有该租户的管理员才知道。@GarethMcCaughan每个租户将有一个指定为管理员的用户,并且只有他应该知道该密钥。+1用于PBE。请详细说明“但在您的用例中,它只会在加密期间保护私钥”。使用公钥/私钥的原因最终是为了能够在不必共享私钥的情况下加密数据。如果您同时在同一系统上加密和解密数据,那么PKI就没有太多意义。它在不同的系统和/或时间框架上可能有意义。Thx但是在何处以及如何存储密码(由readPasswd(System.in)返回)。这个想法是从租户管理员那里获得一次密码并将其存储在某个地方。只需做一点工作,您就可以将其存储在密钥存储中。看看这篇博文。密钥存储依次受密码保护;在某个时刻,您必须在系统中存储一个(哈希)密码,或者要求用户提供关于创建哈希并存储它的更好方法的任何好的建议。您可以将其存储在数据库中,假设在数据库上实施了良好的安全策略,那么在那里应该是安全的。如果这对您的应用程序来说是过度杀伤力,那么另一个(不太安全的)选择是将其放入一个文件中。无论如何,在某个时刻,你需要停下来说“好”,这已经足够安全了。否则,您将不得不担心…PBEWithMD5andDES的密码的密码已过期。您可以使用与PBKDF2相同的代码(java可能将其作为PBKDF2 SHA1)
PBEKeySpec pbeKeySpec;
PBEParameterSpec pbeParamSpec;
SecretKeyFactory keyFac;
// Salt
byte[] salt = {
(byte)0xc7, (byte)0x73, (byte)0x21, (byte)0x8c,
(byte)0x7e, (byte)0xc8, (byte)0xee, (byte)0x99
};
// Iteration count
int count = 20;
// Create PBE parameter set
pbeParamSpec = new PBEParameterSpec(salt, count);
// Prompt user for encryption password.
// Collect user password as char array (using the
// "readPasswd" method from above), and convert
// it into a SecretKey object, using a PBE key
// factory.
System.out.print("Enter encryption password: ");
System.out.flush();
pbeKeySpec = new PBEKeySpec(readPasswd(System.in));
keyFac = SecretKeyFactory.getInstance("PBEWithMD5AndDES");
SecretKey pbeKey = keyFac.generateSecret(pbeKeySpec);
// Create PBE Cipher
Cipher pbeCipher = Cipher.getInstance("PBEWithMD5AndDES");
// Initialize PBE Cipher with key and parameters
pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);
// Our cleartext
byte[] cleartext = "This is another example".getBytes();
// Encrypt the cleartext
byte[] ciphertext = pbeCipher.doFinal(cleartext);