10

Given final block not properly padded私のアプリケーションは Windows では動作しますが、Linux では例外で失敗します。

構成:

  • 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

この問題を解決するにはどうすればよいですか?

4

3 に答える 3

2

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

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

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

キーの導出には、代わりに PBKDF2 などの関数を使用してみてください。処理方法については、stackoverflow で十分です。

于 2012-09-20T20:45:18.150 に答える
0

エラーは、エンコードされたデータが原因のようです。BASE64Decoder は 4 の倍数を返し、Cipher は 8 の倍数を期待しています。

于 2012-09-30T11:35:00.547 に答える