2017-09-22 2 views
2

J'essaie d'écrire une classe d'utilitaire de cryptage/décryptage, mais peu importe ce que je fais, je n'arrive pas à faire fonctionner le décryptage. Je continue d'obtenir une exception javax.crypto.BadPaddingException: Given final block not properly padded lors du décryptage.javax.crypto.BadPaddingException: Étant donné que le bloc final n'est pas correctement rembourré - AES/CBC/PKCS5PADDING

J'ai regardé un certain nombre d'exemples et les autres questions de débordement de la pile mais ne peut pas sembler trouver mon erreur

public class EncryptionUtil { 

    private static final Log LOGGER = LogFactory.getLog(EncryptionUtil.class); 
    private static final String CIPHER_MODE = "AES/CBC/PKCS5PADDING"; 
    private static final String CRYPTO_PROPERTIES_PATH = "/crypto.properties"; 
    private static final SecretKeySpec sKey = keySpecFromProperties(); 

    private EncryptionUtil() {} 

    public static byte[] encrypt(byte[] aBytes) { 
     try { 
      SecureRandom lSecureRandom = new SecureRandom(); 
      byte[] ivBytes = new byte[16]; 
      lSecureRandom.nextBytes(ivBytes); 
      IvParameterSpec lSpec = new IvParameterSpec(ivBytes); 
      Cipher cipher = Cipher.getInstance(CIPHER_MODE); 
      cipher.init(Cipher.ENCRYPT_MODE, sKey, lSpec); 
      byte[] encryptedBytes = cipher.doFinal(aBytes); 
      byte[] outBytes = new byte[encryptedBytes.length + 16]; 
      System.arraycopy(ivBytes, 0, outBytes, 0, 16); 
      System.arraycopy(encryptedBytes, 0, outBytes, 16, encryptedBytes.length); 

      return outBytes; 
     } catch (Exception aEx) { 
      LOGGER.error("Failed to encrypt bytes"); 
      throw new RuntimeException(aEx); 
     } 
    } 

    public static byte[] decrypt(byte[] aBytes) { 
     try { 
      byte[] lIvBytes = Arrays.copyOfRange(aBytes, aBytes.length - 16, aBytes.length); 
      byte[] lEncryptedBytes = Arrays.copyOfRange(aBytes, 0, aBytes.length - 16); 
      IvParameterSpec lIvSpec = new IvParameterSpec(lIvBytes); 
      Cipher cipher = Cipher.getInstance(CIPHER_MODE); 
      cipher.init(Cipher.DECRYPT_MODE, sKey, lIvSpec); 
      return cipher.doFinal(lEncryptedBytes); 
     }catch (Exception aEx){ 
      LOGGER.error("Failed to decrypt bytes. Returning input bytes", aEx); 
      return aBytes; 
     } 
    } 

    private static SecretKeySpec keySpecFromProperties(){ 
     try(InputStream lPropStream = EncryptionUtil.class.getResourceAsStream(CRYPTO_PROPERTIES_PATH)){ 
      Properties cryptoProps = new Properties(); 
      cryptoProps.load(lPropStream); 
      String lSecret = cryptoProps.getProperty("secret"); 
      MessageDigest digest = MessageDigest.getInstance("SHA-256"); 
      digest.update(lSecret.getBytes("UTF-8")); 
      byte[] keyBytes = new byte[16]; 
      System.arraycopy(digest.digest(),0, keyBytes, 0, keyBytes.length); 
      return new SecretKeySpec(keyBytes, "AES"); 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 
} 
+0

Vous ne pouvez pas stocker une clé dans un fichier de propriétés. C'est binaire, pas de texte. – EJP

+0

Je convertis la chaîne en octets en utilisant la même solution que dans la réponse ici https://stackoverflow.com/questions/3451670/java-aes-and-using-my-own-key – rykeeboy

Répondre

2

Vous précédez votre IV du cryptogramme sur le cryptage, mais décryptage vous copiez le dernier 16 octets en tant que votre IV. Quoi que vous fassiez pour le cryptage, vous devez l'annuler lors du décryptage.

+0

Merci, je l'avais dans l'autre sens autour quand essayer quelque chose d'autre et j'ai oublié de le changer – rykeeboy