2012-09-20 2 views
9

私のアプリケーションはウィンドウでは動作しますが、Linuxでは例外が発生します。例外:Linuxで "最終ブロックに適切な埋め込みができませんでした"が、Windowsで動作します

構成:

  • JDKのバージョン:1.6
  • のWindows:バージョン7
  • のLinux:CentOSの5.8 64ビット

私のコードは以下の通りです:

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; 
    } 
} 

で行:

ciper.doFilnal(raw); 

次の例外がスローされます。

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

私はこの問題をどのように修正することができますか?

+1

私はあなたがセキュリティを気にしないことを願っています。 DESとECBの両方は、疑わしい選択です。 – CodesInChaos

+0

'SecureRandom'はすべてのプラットフォームで同じように動作すると仮定しています。 Javaはそれを保証しますか? PRNGではなく、キーを導出するためにKDFを使用します。 – CodesInChaos

+0

'raw'には両方のプラットフォームで同じデータが含まれていますか?私は 'decodeKey()'にデータを渡す前に間違ったエンコーディングの変換を行っていると思われますが、base64を使用しているとは思いません。 – axtavt

答えて

2

回答は特定のランタイムでSecureRandomシードが異なる可能性があります。ほとんどの場合、すぐにシードされない"SHA1PRNG"が得られます。代わりに、任意のランダムを要求する前にsetSeed()を呼び出すことができます。その場合、シードはエントロピーのソースとしてのみ使用されます。この場合、あなたの鍵は常に同じです。

問題は、SecureRandomが返されるという定義がないことです。上記に該当しない全く異なるプラットフォーム固有の実装が得られるかもしれません。別のプロバイダが優先される場合は、Sunプロバイダの1つを取得できない場合があります。

シードに問題があります。シードはgetBytes()へのコール中にseedStr変数のプラットフォームのデフォルトエンコードを使用しました。エンコードが異なる可能性があるため、種子が異なる可能性があり、その結果も異なります。

キー導出の代わりにPBKDF2などの機能を使用してください。実行する方法については、stackoverflowで十分です。それが原因でエンコードされたデータのようだ

+1

誰かありますか?これは助けになりましたか?あなたの問題を解決しましたか?報告してください! –

+0

それは動作します!ありがとう!! – user1685364

+0

これはあなたの問題を解決したことを嬉しく思っています。答えを受け入れるといいでしょう。 –

0

エラー、BASE64Decoderは4の倍数を返しますし、次のように暗号が8

0

の倍数を期待している:私は内容を変更する必要がありました。

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) { 
} 

}仕事の

これ!!ありがとう!!!

+0

素晴らしいですが、乱数生成器が実際に乱数を生成するときに不平を言うことはありません。 –

関連する問題