Java对称加密方法

时间:2014-04-25 12:26:57

标签: java encryption aes

我有一个用Java编写的RESTful API,我想保护该API的外部配置文件。

我尝试使用以下对称加密方法保护它:

private final static String passPhrase = "My Super Ultra Passphrase";
private final static byte[] salt = "My Super Ultra Salt".getBytes();
private final static int iterations = 8192;
private static String strIv = "";

private static String encryptText(String text) {
    String result = "";
    try {
        // create the key for encryption
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        SecretKey secret = factory.generateSecret(
                new PBEKeySpec(passPhrase.toCharArray(), salt, iterations, 128));
        SecretKeySpec key = new SecretKeySpec(secret.getEncoded(), "AES");

        // encrypts the text
        Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
        aes.init(Cipher.ENCRYPT_MODE, key);
        byte[] cipherText = aes.doFinal(text.getBytes());
        byte[] iv = aes.getIV();

        result = new String(Base64.encode(cipherText));
        strIv = new String(Base64.encode(iv));

    } catch (NoSuchAlgorithmException 
            | InvalidKeySpecException 
            | NoSuchPaddingException 
            | InvalidKeyException 
            | IllegalBlockSizeException 
            | BadPaddingException e) {
        e.printStackTrace();
    }
    return result;
}

private static String decryptText(String text) {
    String result = "";
    try {
        // create the key for decryption
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        SecretKey secret = factory.generateSecret(
                new PBEKeySpec(passPhrase.toCharArray(), salt, iterations, 128));
        SecretKeySpec key = new SecretKeySpec(secret.getEncoded(), "AES");

        byte[] iv = Base64.decode(strIv);
        byte[] cipherText = Base64.decode(text);

        // decrypt the text
        Cipher aes = Cipher.getInstance("AES/CBC/PKCS5Padding");
        aes.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec(iv));
        result = new String(aes.doFinal(cipherText));

    } catch (NoSuchAlgorithmException 
            | InvalidKeySpecException 
            | NoSuchPaddingException 
            | InvalidKeyException 
            | IllegalBlockSizeException 
            | BadPaddingException 
            | InvalidAlgorithmParameterException
            | Base64DecodingException e) {
        e.printStackTrace();
    }
    return result;
}

我的问题是:这段代码是否相当强大?

2 个答案:

答案 0 :(得分:2)

你想要为自己辩护,究竟是针对哪种攻击方案?我会回答做出一些假设,如果我错了,请纠正。

如果要保护配置文件,那么您正在尝试防御已获得对服务器文件的读取权限的攻击者。在这种情况下,此攻击者也可以下载程序本身并使用调试器提取密钥,因为它是硬编码的。这是一个额外的防御层,可能会让一些攻击者放弃,但只能推迟其他人。

希望它有所帮助。

答案 1 :(得分:2)

嗯,这很难回答。目前你的IV和你的盐都不是随机的,所以这肯定是一个容易修复的错误。您确实添加了身份验证标记,因此可能无法读取您的配置(保密),但可能会更改。如果您从一个系统转到另一个系统,您可能会在String.getBytes()上获得不同的结果,因此可能是一个与安全无关的问题。

另一方面,在CBC模式下使用PBKDF2和AES可能是一个好主意。如果你遵守那些密码短语,8Ki迭代可能还不够。

请注意,我假设密码实际上不是静态字符串,如果是这种情况,请查看jspurim的答案。