【问题标题】:Android Cipher AES/GCM/NoPadding "iv==null"Android 密码 AES/GCM/NoPadding "iv==null"
【发布时间】:2016-11-14 08:09:59
【问题描述】:

尝试在 Marshmallow 上加密和解密一些数据。加密效果很好,但在尝试解密时,我得到了一个 RuntimeException,说“iv == null”。

基本上,cipher.getIV() 和 cipher.getParameters() 返回 null。 我错过了什么吗?

  private static final String ALGORITHM_NAME = "AES/GCM/NoPadding";
  private static final int IV_SIZE = 128;
  private static final int ALGORITHM_SIZE = 256;

  private static final String KEYSTORE_PROVIDER = "AndroidKeyStore";
  private static final String SYMMETRIC_ALIAS = "secret_key";

  private static SecretKey getSymmetricKey()
      throws NoSuchProviderException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, IOException,
      CertificateException, KeyStoreException, UnrecoverableEntryException {

    KeyStore ks = KeyStore.getInstance(KEYSTORE_PROVIDER);
    ks.load(null);

    return (SecretKey) ks.getKey(SYMMETRIC_ALIAS, null);
  }

  private static SecretKey createSecretKey()
      throws NoSuchAlgorithmException, NoSuchProviderException, InvalidAlgorithmParameterException {

    KeyGenerator keyGenerator = KeyGenerator.getInstance(
        KeyProperties.KEY_ALGORITHM_AES, KEYSTORE_PROVIDER);

    keyGenerator.init(new KeyGenParameterSpec.Builder(SYMMETRIC_ALIAS,
        KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)
        .setBlockModes(KeyProperties.BLOCK_MODE_GCM)
        .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE)
        .setKeySize(ALGORITHM_SIZE)
        .setRandomizedEncryptionRequired(true)
        .setUserAuthenticationRequired(false)
        .build());

    return keyGenerator.generateKey();
  }

  public static byte[] encrypt(byte[] data)
      throws CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException,
      KeyStoreException, NoSuchProviderException, InvalidAlgorithmParameterException, NoSuchPaddingException,
      InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

    SecretKey secretKey = getSymmetricKey();
    if (secretKey == null) {
      secretKey = createSecretKey();
    }

    Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    return cipher.doFinal(data);
  }

  public static byte[] decrypt(byte[] data)
      throws CertificateException, NoSuchAlgorithmException, IOException, UnrecoverableEntryException,
      KeyStoreException, NoSuchProviderException, InvalidAlgorithmParameterException, NoSuchPaddingException,
      InvalidKeyException, BadPaddingException, IllegalBlockSizeException {

    SecretKey secretKey = getSymmetricKey();

    Cipher cipher = Cipher.getInstance(ALGORITHM_NAME);
    GCMParameterSpec spec = new GCMParameterSpec(IV_SIZE, cipher.getIV());
    cipher.init(Cipher.DECRYPT_MODE, secretKey, spec);
    return cipher.doFinal(data.getBytes());
  }

【问题讨论】:

  • 我遇到了类似的问题,你能帮我解决这个问题吗

标签: android encryption initialization-vector aes-gcm


【解决方案1】:

解密时您必须向 AES/GCM/NoPadding Cipher.init 提供非空 IV。但是,您的代码提供了一个 null IV,它是通过在未初始化的 Cipher 实例上调用 Cipher.getIV() 获得的。

解决方法是保存加密时使用的 IV,然后在解密时使用相同的保存的 IV。

【讨论】:

  • IV 不需要保密,但对于 GCM 来说必须是唯一的。由于它始终具有相同的长度,因此您可以简单地将其添加到密文中并在解密之前将其切掉。
猜你喜欢
  • 2021-09-24
  • 2018-02-19
  • 2021-02-06
  • 2019-02-20
  • 2015-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
相关资源
最近更新 更多