如何使用PBE算法解密字符串

时间:2017-04-03 16:50:26

标签: java encryption cryptography passwords aes

我有一个PBE生成的密钥,我使用算法加密了一个字符串" PBEWithHmacSHA256AndAES_128"但我无法破译上述字符串。

密钥生成:

private final static byte[] SALT = { (byte) 0xc9, (byte) 0x36, (byte) 0x78, (byte) 0x99, (byte) 0x52, (byte) 0x3e, (byte) 0xea,
        (byte) 0xf2 };

PBEKeySpec keySpec = new PBEKeySpec(pwd.toCharArray(), SALT, 20 , 128);     
    try {
        SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128");
        PRIVATE_KEY = kf.generateSecret(keySpec);
    } catch (NoSuchAlgorithmException | InvalidKeySpecException  e) {
        e.printStackTrace();
    }

Encypt String:

private static String cipherString(String string) {


    PBEParameterSpec pbeParameterSpec = new PBEParameterSpec(SALT, 100);
    Cipher cipher;
    try {
        cipher = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
        cipher.init(Cipher.ENCRYPT_MODE, PRIVATE_KEY, pbeParameterSpec);
        byte[] input = string.getBytes();
        byte[] encryptedp = cipher.doFinal(input);

        return encryptedp.toString();
    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException | IllegalBlockSizeException | BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

解密字符串:

private static String decipherString(String string) {
    Cipher c;
    try {
        c = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");

        c.init(Cipher.DECRYPT_MODE, PRIVATE_KEY);

        byte[] input = string.getBytes();
        byte[] encryptedp = c.doFinal(input);

        return encryptedp.toString();

    } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    return null;
}

1 个答案:

答案 0 :(得分:1)

只需使用以下适用于J2SE的代码即可。由于算法PBEWithHmacSHA256AndAES_128在内部使用CBC模式的AES,我们还必须提供IV,这是我随机生成的示例。您必须使用相同的IV进行加密和解密。出于安全原因,您应使用新的随机IV并将其与加密文本一起保存。

    SecureRandom rnd = new SecureRandom();
    byte[] iv = new byte[16];
    rnd.nextBytes(iv);

    String password = "password";
    byte[] plaintext = "plaintext".getBytes(StandardCharsets.UTF_8);

    IvParameterSpec ivParamSpec = new IvParameterSpec(iv);
    PBEParameterSpec pbeParamSpec = new PBEParameterSpec(SALT, 10000, ivParamSpec);
    PBEKeySpec keySpec = new PBEKeySpec(password.toCharArray());
    try {
        SecretKeyFactory kf = SecretKeyFactory.getInstance("PBEWithHmacSHA256AndAES_128");
        SecretKey secretKey = kf.generateSecret(keySpec);

        // On J2SE the SecretKeyfactory does not actually generate a key, it just wraps the password.
        // The real encryption key is generated later on-the-fly when initializing the cipher
        System.out.println(new String(secretKey.getEncoded()));

        // Encrypt
        Cipher enc = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
        enc.init(Cipher.ENCRYPT_MODE, secretKey, pbeParamSpec);
        byte[] encrypted = enc.doFinal(plaintext);
        System.out.println("Encrypted text: " + new BASE64Encoder().encode(encrypted));

        // Decrypt
        Cipher dec = Cipher.getInstance("PBEWithHmacSHA256AndAES_128");
        dec.init(Cipher.DECRYPT_MODE, secretKey, pbeParamSpec);
        byte[] decrypted = dec.doFinal(encrypted);
        String message = new String(decrypted, StandardCharsets.UTF_8);

        System.out.println(message);

    } catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
        e.printStackTrace();
    }