使用Java中的对称加密在磁盘上保护私钥

时间:2011-02-19 02:45:39

标签: java cryptography encryption-asymmetric public-key-encryption encryption-symmetric

我有一个分布式应用程序,它从中央服务器轮询命令,这些命令的内容由私钥“签名”,公钥与每个远程站点的应用程序一起部署。每个命令都使用私钥进行签名,并在执行命令之前验证该签名。

以下是我在java中生成公钥/私钥对的方法。 (我知道,我们应该做的比1024更多)

KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();

新要求是,除了发送简单相对安全的命令外,我们现在还希望发送命令,指示我们的软件下载并执行安装程序以自行更新。如果没有正确完成,这有可能打开一个大洞。 “执行更新安装程序”命令将一如既往地进行签名,并且还将包含将被下载和运行的可执行文件的md5。因此,命令上的签名必须正确(并且将包括md5),然后在执行将发生之前,在下载的文件上计算的md5将需要是正确的。这应该照顾我能想到的大多数攻击向量。 我应该关注的其他任何人?

所以,现在我引导我注意保护这些命令所在的服务器上的私钥。如果获得该私钥,则游戏结束。我该如何在磁盘上保护该密钥?

我的想法是使用带密码的对称加密来保护该私钥。

我目前的解决方案如下:

char[] passphrase; // Actual passphrase
PrivateKey privateKeyObj; // Actual Private Key
byte[] privateKeyBytes = privateKeyObj.getEncoded();

byte[] salt = new byte[8];
new SecureRandom().nextBytes(salt);

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
KeySpec spec = new PBEKeySpec(passphrase, salt, 1024, 256);
SecretKey tmp = factory.generateSecret(spec);
SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secret);
AlgorithmParameters params = cipher.getParameters();
byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();

byte[] ciphertext = cipher.doFinal(privateKeyBytes);

FileOutputStream outputFileStream = new FileOutputStream(outputFile);
outputFileStream.write(salt);
outputFileStream.write(iv);
outputFileStream.write(ciphertext);
outputFileStream.close();

(为清晰起见,删除了例外情况)

这基本上随机生成一个salt,使用密码来提出密钥,然后将生成的salt,IV和密文存储在准备解密的文件中。

然而,我觉得这里缺少一些东西。就像我也应该以某种方式在键上包含某种类型的MAC,以便我知道我得到了有效的描述?也许这很简单,只需在私钥之前放入5或6个字节的已知文本即可?一个糟糕的密码现在只会导致填充异常错误,但我读到这可能并非总是如此,一些糟糕的密码将解码并导致垃圾。我觉得我需要防范这一点。

如果我在这里正确的轨道并且提供一些反馈,有人可以告诉我。重要的是我尽可能保证安全。

2 个答案:

答案 0 :(得分:1)

包含哈希值或HMAC是合理的,因为您想知道您的密码错误输入。否则,您的解决方案对我来说是合理的。

您可以做的另一件事是尽可能安全地存储它:让它脱机。将副本放在几个USB钥匙上,将其存放在一个安全的地方但是可以放在手中,并将备份存放在保险箱或律师手中。如果它在物理上无法访问,就会听到秘密密钥。

答案 1 :(得分:0)

在某些情况下,可能会使用不使用HMAC或众所周知的前缀来使攻击者更难破解。请注意,如果您不包含HMAC,在某些情况下(由填充损坏导致)仍然会解码异常,这足以识别错误的密码。