Расшифровка зашифрованных данных, которые были зашифрованы в соответствии с официальной документацией Google

#android #android-biometric-prompt #android-biometric

Вопрос:

Я успешно зашифровал данные, используя поток биометрического менеджера, как показано в Google, но при попытке расшифровать зашифрованные данные я продолжаю нажимать на предложение IllegalBlockSizeException. Мне нужна помощь, пожалуйста.

Это мой класс, который обрабатывает все шифрование отпечатков пальцев( которое хорошо работает), но расшифровка не работает, так как он продолжает попадать в предложение IllegalBlockSizeException

 public class FingerPrintEncrypter {  private static FingerPrintEncrypter fingerPrintEncrypter;  private static final String ENCRYPTION_BLOCK_MODE = KeyProperties.BLOCK_MODE_CBC;  private static final String ENCRYPTION_PADDING = KeyProperties.ENCRYPTION_PADDING_PKCS7;  private static final String ENCRYPTION_ALGORITHM = KeyProperties.KEY_ALGORITHM_AES;  private static final String ANDROID_KEY_STORE = "AndroidKeyStore";  byte[] initVector;   private FingerPrintEncrypter(){   }   public static synchronized FingerPrintEncrypter getInstance(){  if(fingerPrintEncrypter == null){  fingerPrintEncrypter = new FingerPrintEncrypter();  }  return fingerPrintEncrypter;   }   /*  gets the Cipher obj in encryptionMode for encryption tasks.  */  public Cipher getCipherForEncryption(String aliasKeyName){  try {  Cipher cipher = getCipher();  SecretKey secretKey = getOrCreateSecreteKey(aliasKeyName);  cipher.init(Cipher.ENCRYPT_MODE, secretKey);  initVector = cipher.getIV();  return cipher;  } catch (InvalidKeyException e) {  e.printStackTrace();  }  return null;  }   /*  gets the Cipher obj in decryptionMode for decryption tasks.  */  public Cipher getCipherForDecryption(String aliasKeyName){  try{  Cipher cipher = getCipher();  SecretKey secretKey = getOrCreateSecreteKey(aliasKeyName);  IvParameterSpec decryptParamSpec = new IvParameterSpec(initVector);  cipher.init(Cipher.DECRYPT_MODE, secretKey, decryptParamSpec);  return cipher;  }catch (InvalidKeyException e){  e.printStackTrace();  } catch (InvalidAlgorithmParameterException e) {  e.printStackTrace();  }  return null;  }   private SecretKey getOrCreateSecreteKey(String aliasKeyName) {  try {  KeyStore keyStore = KeyStore.getInstance(ANDROID_KEY_STORE);  keyStore.load(null);  SecretKey key = ((SecretKey)keyStore.getKey(aliasKeyName, null));  if(key == null){  // key previously create so just grab it  generateSecretKey(aliasKeyName);  }  return key;  } catch (KeyStoreException e) {  e.printStackTrace();  } catch (CertificateException e) {  e.printStackTrace();  } catch (NoSuchAlgorithmException e) {  e.printStackTrace();  } catch (IOException e) {  e.printStackTrace();  } catch (UnrecoverableKeyException e) {  e.printStackTrace();  }  return null;  }   private void generateSecretKey(String aliasKeyName){  try {  // key not create create a new one  KeyGenParameterSpec parameterSpec = new KeyGenParameterSpec.Builder(aliasKeyName,  KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT)  .setBlockModes(ENCRYPTION_BLOCK_MODE)  .setEncryptionPaddings(ENCRYPTION_PADDING)  .setUserAuthenticationRequired(true)  .build();   KeyGenerator keyGenerator = KeyGenerator.getInstance(ENCRYPTION_ALGORITHM, ANDROID_KEY_STORE);  keyGenerator.init(parameterSpec);  keyGenerator.generateKey();  } catch (NoSuchAlgorithmException e) {  e.printStackTrace();  } catch (NoSuchProviderException e) {  e.printStackTrace();  } catch (InvalidAlgorithmParameterException e) {  e.printStackTrace();  }  }    private Cipher getCipher() {  try {  return Cipher.getInstance(ENCRYPTION_ALGORITHM   "/"    ENCRYPTION_BLOCK_MODE   "/"    ENCRYPTION_PADDING);  } catch (NoSuchAlgorithmException e) {  e.printStackTrace();  } catch (NoSuchPaddingException e) {  e.printStackTrace();  }  return null;  }   public String encryptData(String info, Cipher cipher){  try {  byte[] encryptedData = cipher.doFinal(info.getBytes("UTF-8"));  return Base64.encodeToString(encryptedData, Base64.NO_WRAP);  } catch (BadPaddingException e) {  e.printStackTrace();  } catch (IllegalBlockSizeException e) {  e.printStackTrace();  } catch (UnsupportedEncodingException e) {  e.printStackTrace();  }  return null;  }   public String decryptData(String stringToDecrypt, Cipher cipher){  try {  return new String(cipher.doFinal(Base64.decode(stringToDecrypt, Base64.NO_WRAP)));  } catch (BadPaddingException e) {  e.printStackTrace();  } catch (IllegalBlockSizeException e) {  e.printStackTrace();  }  return null;  }   }  

Комментарии:

1. Одна вещь, которую я задаюсь вопросом, так как я каждый раз генерирую новый IV, всегда ли инициатор IV, который вы получаете от шифра, остается неизменным или он каждый раз генерирует новые инициаторы? В этом случае было бы трудно получить правильный IV для вашего дешифрующего шифра. Тем не менее, если мне не изменяет память (я также потратил много времени на поиск подобных проблем), похоже, у вас могут возникнуть проблемы с заполнением

2. Я помню, что большой проблемой для меня был неправильный размер бита в IV, но если cipher.getIV() работает так, как вы его используете, то я полагаю, что класс шифра должен дать вам рабочий

3. ну, это тоже предполагается, но, честно говоря, я не знаю, почему я продолжаю получать эту ошибку, и официальный документ Google тоже не помогает показать, как работает процесс расшифровки.

4. Но теперь, если вы шифруете значение, вы назначаете свой байт[] initVector. Затем, если вы сохраните то, что зашифровали, перезагрузите приложение и попытаетесь расшифровать данные, не попытается ли оно расшифровать их с помощью нулевого байта[] initVector, если вы ничего не шифровали раньше (для настройки initVector)?

5. Проблема заключалась в том, что байт[] initVector, переданный в IVParameterSpec, должен был быть вызван, как я предполагал, из cipher.getIV (), если только шифр выполнял шифрование, а не раньше.