2016-11-19 3 views
0

Nous avons récemment migré notre infrastructure de Solaris (Oracle/Sun Java) vers AIX (IBM Java). Nos clients vont télécharger un fichier crypté en utilisant l'algorithme (AES) et la clé partagée par nous, une fois que les fichiers cryptés sont placés dans notre serveur, une routine de traitement par lots va décrypter en utilisant la même clé. Cela fonctionnait bien jusqu'à la migration, mais après la migration, la fonctionnalité de décryptage AES ne fonctionne pas.Le décryptage AES fonctionne avec la boîte Solaris SunJCE mais ne fonctionne pas dans la boîte AIX avec IBMJCE

Plus tôt, nous avons utilisé

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding", "SunJCE"); 

post-migration, nous avons changé comme

Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 

Lorsque lot est en cours d'exécution, nous obtenons exception comme ci-dessous

javax.crypto.IllegalBlockSizeException : Longueur d'entrée (avec remplissage) non multiple de 16 octets at com.ibm.crypto.provider.AESCipher.a (Inconnu n Source) à com.ibm.crypto.provider.AESCipher.engineDoFinal (source inconnue) à com.ibm.crypto.provider.AESCipher.engineDoFinal (source inconnue) à javax.crypto.Cipher.doFinal (source inconnue)

Le code utilisé pour le décryptage

private byte[] decrypt(byte[] data, String corporateId, String algorithm) 
     throws Exception { 
    String path = corporateId + ".key"; 

    byte[] key = (byte[]) null; 
    try { 
     key = returnbyte(path); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); 
    this.logger.info("Provider Info " + cipher.getProvider().getInfo()); 
    byte[] keyBytes = new byte[16]; 

    int len = key.length; 
    if (len > keyBytes.length) { 
     len = keyBytes.length; 
    } 
    System.arraycopy(key, 0, keyBytes, 0, len); 
    SecretKeySpec keySpec = new SecretKeySpec(keyBytes, "AES"); 

    IvParameterSpec ivSpec = new IvParameterSpec(keyBytes); 
    cipher.init(2, keySpec, ivSpec); 
    BASE64Decoder decoder = new BASE64Decoder(); 

    byte[] results = decoder.decodeBuffer(hexStringFromBytes(data)); 

    byte[] ciphertext = cipher.doFinal(results); 

    return ciphertext; 
} 

hexStringFromBytes Méthode:

public static String hexStringFromBytes(byte[] ba) { 
    StringBuffer sb = new StringBuffer(); 
    for (int i = 0; i < ba.length; i++) { 
     if ((i > 0) && ((i & 0x1F) == 0)) { 
      sb.append("\n"); 
     } else if ((i > 0) && ((i & 0x3) == 0)) { 
      sb.append(""); 
     } 
     sb.append(hexChars[((0xF0 & ba[i]) >> 4)]); 
     sb.append(hexChars[(0xF & ba[i])]); 
    } 
    return sb.toString(); 
} 

Pas sûr de la cause du problème, cipher.doFinal(results); se produit erreur.

Le chargeur de classe indique également que le fournisseur IBMJCE est utilisé. Frappé avec ce problème pendant 3 jours. Toute direction ou orientation pour résoudre le problème est très appréciée. Merci d'avance.

+0

L'entrée est-elle un multiple exact aller à la taille du bloc (16 octets pour AES)? Déboguer et découvrir et ce n'est pas pourquoi. – zaph

+3

vous prenez votre 'byte []' données, le convertir en une chaîne hexadécimale, puis base64 décoder cela? Cela n'a aucun sens. –

+0

Notez que l'OP est un "architecte technique". – zaph

Répondre

1

Le problème est probablement lié à votre rembourrage. Comme il est dit "Longueur d'entrée (avec remplissage) pas multiple de 16 octets". Comme je l'ai trouvé dans les questions précédentes, le ne convient pas à AES, la cause taille de bloc AES est 16, pas 8, Vous trouverez ci-dessous:

AES/CBC/PKCS5Padding vs AES/CBC/PKCS7Padding with 256 key size performance java

Vous devez donc essayer d'utiliser un autre algorithme de remplissage pour pour travailler.

+0

Il est préférable d'utiliser une implémentation qui fait du remplissage PKCS # 7 (née PKCS # 5) en sélectionnant simplement une option, la plupart le font. – zaph

+0

Dans le cas de Java PKCS5Padding fait effectivement le remplissage PKCS # 7, ce n'est pas le problème ici. –