0

我正在尝试创建一个简单的加密和解密类。两种方法都给出相同的字符串。我有点困惑。请需要帮助。

这是我的代码片段:

public class UltimateEncryptor {

  private static final String CIPHER_ALGORITHM = "AES/CBC/PKCS5Padding";
  private static final String RANDOM_GENERATOR_ALGORITHM = "AES";


  // Encrypts string and encodes in Base64
  public String encrypt( String password, String data ) throws Exception 
  {
    byte[] secretKey = password.getBytes();
    byte[] clear = data.getBytes();

    SecretKeySpec secretKeySpec = new SecretKeySpec( secretKey, CIPHER_ALGORITHM );
    Cipher cipher = Cipher.getInstance( CIPHER_ALGORITHM );
    cipher.init( Cipher.ENCRYPT_MODE, secretKeySpec );

    byte[] encrypted = cipher.doFinal( clear );
    String encryptedString = Base64.encodeToString( encrypted, Base64.DEFAULT );

    return encryptedString;
  }

  // Decrypts string encoded in Base64
  public String decrypt( String password, String encryptedData ) throws Exception 
  {
    byte[] secretKey = password.getBytes();
    SecretKeySpec secretKeySpec = new SecretKeySpec( secretKey, CIPHER_ALGORITHM );
    Cipher cipher = Cipher.getInstance( CIPHER_ALGORITHM );
    cipher.init( Cipher.DECRYPT_MODE, secretKeySpec );

    byte[] encrypted = Base64.decode( encryptedData, Base64.DEFAULT );
    byte[] decrypted = cipher.doFinal( encrypted );

    return new String( decrypted );
  }
}
4

1 回答 1

0

您的代码有几个错误,但离工作不远了。以下是问题:

  1. 你应该传递RANDOM_GENERATOR_ALGORITHM给你的SecretKeySpec构造函数,而不是CIPHER_ALGORITHM.

  2. 您需要为加密和解密指定 IV。如果不指定 IV,解密将不起作用,因为加密将使用随机 IV,并且您的解密方法将不知道该值是什么。

    cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, 
        new IvParameterSpec(/* 16 byte value */));
    
    cipher.init(Cipher.DECRYPT_MODE, secretKeySpec, 
        new IvParameterSpec(/* same 16 byte value */));
    

    请注意,您必须将 IV 与密文一起存储,以便用于解密。一种常见的方法是在密文值前面加上 IV(注意:IV 不是敏感值)。每次加密时都应该使用随机 IV 值。

其他一些评论:

  1. 您的方法应该是static因为它们不使用任何实例字段。

  2. 您不应该使用密码的原始字节作为密钥。相反,您应该使用类似 PBKDF2的密码从密码中派生密钥。

如果您想查看一些正确执行此操作的代码,请参阅JNCryptor。这是一个与 Android 兼容的 Java 库,可以进行基于密码的加密和解密。特别是,查看源代码以查看:

于 2013-04-22T07:52:45.117 回答