2012-09-20 10 views
9

La mia applicazione funziona in Windows, ma fallisce in Linux con l'eccezione Given final block not properly padded.Eccezione: "Dato il blocco finale non adeguatamente riempito" in Linux, ma funziona in Windows

Configurazione:

  • JDK Versione: 1.6
  • di Windows: la versione 7
  • Linux: CentOS 5.8 a 64 bit

Il mio codice è qui sotto:

import java.io.IOException; 
import java.io.UnsupportedEncodingException; 
import java.security.InvalidKeyException; 
import java.security.Key; 
import java.security.NoSuchAlgorithmException; 
import java.security.SecureRandom; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.KeyGenerator; 
import javax.crypto.NoSuchPaddingException; 

import sun.misc.BASE64Decoder; 
import sun.misc.BASE64Encoder; 

public class SecurityKey { 
    private static Key key = null; 
    private static String encode = "UTF-8"; 
    private static String cipherKey = "DES/ECB/PKCS5Padding"; 

    static { 
     try { 
      KeyGenerator generator = KeyGenerator.getInstance("DES"); 
      String seedStr = "test"; 
      generator.init(new SecureRandom(seedStr.getBytes())); 
      key = generator.generateKey(); 
     } catch(Exception e) { 
     } 
    } 

    // SecurityKey.decodeKey("password") 
    public static String decodeKey(String str) throws Exception { 
     if(str == null) 
      return str; 

     Cipher cipher = null; 
     byte[] raw = null; 
     BASE64Decoder decoder = new BASE64Decoder(); 
     String result = null; 
     cipher = Cipher.getInstance(cipherKey); 
     cipher.init(Cipher.DECRYPT_MODE, key); 
     raw = decoder.decodeBuffer(str); 
     byte[] stringBytes = null; 
     stringBytes = cipher.doFinal(raw); // Exception!!!! 
     result = new String(stringBytes, encode); 

     return result; 
    } 
} 

A la linea:

ciper.doFilnal(raw); 

la seguente eccezione viene generata:

javax.crypto.BadPaddingException: Given final block not properly padded 

Come posso risolvere questo problema?

+1

Spero che non ti preoccupi per la sicurezza. Sia DES che ECB, sono una scelta dubbia. – CodesInChaos

+0

Si presume che 'SecureRandom' si comporta allo stesso modo su tutte le piattaforme. Java lo garantisce? Usa un KDF per ottenere una chiave e non un PRNG. – CodesInChaos

+0

Sei sicuro che 'raw' contenga gli stessi dati su entrambe le piattaforme? Sospetto una copia di codifica sbagliata prima di passare i dati a 'decodeKey()', anche se è improbabile se si usa base64. – axtavt

risposta

2

La risposta sta nel fatto che il seeding SecureRandom può essere diverso per i tempi di esecuzione specifici. La maggior parte delle volte si ottiene "SHA1PRNG", che non verrà seminato immediatamente. Invece, è possibile chiamare setSeed() prima di richiedere qualsiasi casuale, e in tal caso quel seme viene utilizzato come unica fonte di entropia. In questo caso la tua chiave sarà sempre la stessa.

Il problema è che non viene definito quale SecureRandom viene restituito. Potresti ottenere un'implementazione completamente diversa e specifica per la piattaforma per la quale quanto sopra non è vero. Potresti non ottenere quello del fornitore Sun, se un altro provider ha la precedenza.

Quindi c'è il problema con il seme. Il seed ha utilizzato la codifica predefinita della piattaforma per la variabile seedStr durante la chiamata a getBytes(). Poiché le codifiche possono differire, i semi possono differire e quindi anche il risultato sarà diverso.

Provare a utilizzare una funzione come PBKDF2 invece per la derivazione della chiave; c'è abbastanza sullo stackoverflow su come procedere.

+1

Chiunque? Questo aiuto? Hai risolto il tuo problema? Si prega di segnalare! –

+0

Funziona !! Grazie!! – user1685364

+0

Grande che questo ha risolto il tuo problema, sarebbe bello se accettassi la risposta. –

0

errore pare a causa dei dati codificati, BASE64Decoder tornerà multipli di 4 e Cipher si aspetta multipli di 8.

0

come segue: I dovuto modificare il contenuto.

static{ 
    try { 
    KeyGenerator generator = KeyGenerator.getInstance("DES"); 
    String seedStr = "test"; 
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG"); 
    random.setSeed(seedStr.getBytes()); 
    generator.init(random); 
    key = generator.generateKey(); 
} catch(Exception e) { 
} 

}

E 'il lavoro di !! Grazie!!!

+0

Fantastico, ma non vieni a lamentarti quando il generatore di numeri casuali genera effettivamente numeri casuali. –

Problemi correlati