1

Java クライアントからメッセージを受信する Java HTTP サーバーがあります。

サーバーとクライアントの両方が同じ Encrypter クラスを使用します。

public class Encrypter {

    private Cipher cipher; //The encryption cipher object
public static final String ALGORITHM = "Blowfish"; //Encryption Algorithm

    /**
     * Constructor
     */
    public Encrypter()
    {       
        try {
            initlizeCipher();
        } catch (Throwable e) {     
            ServerSettings.LOG.logError(e);
            e.printStackTrace();

        }
    }

    /**
     * Initialize the Cipher object
     * @throws NoSuchAlgorithmException
     * @throws NoSuchPaddingException
     */
    private void initlizeCipher() throws NoSuchAlgorithmException, NoSuchPaddingException
    {       
        cipher = Cipher.getInstance(ServerSettings.ALGORITHM);
    }

    /**
     * Encrypt a String
     * @param string String to encrypt
     * @return an encrypted String
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws UnsupportedEncodingException
     */
    public synchronized String encrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException
    {
        cipher.init(Cipher.ENCRYPT_MODE, ServerSettings.SECRECT_KEY_SPEC);
        byte[] stringBytes = string.getBytes("UTF-8");
        byte[] encryptedBytes = cipher.doFinal(stringBytes);
        return Base64.encodeBytes(encryptedBytes);      
    }

    /**
     * Decrypt a String
     * @param string String to decrypt
     * @return a decrypted String
     * @throws InvalidKeyException
     * @throws IllegalBlockSizeException
     * @throws BadPaddingException
     * @throws IOException
     */
    public synchronized String decrypt(String string) throws InvalidKeyException, IllegalBlockSizeException, BadPaddingException, IOException
    {       
        cipher.init(Cipher.DECRYPT_MODE, ServerSettings.SECRECT_KEY_SPEC);
        byte[] decryptedBytes = Base64.decode(string.getBytes());       
        byte[] encryptedBytes = cipher.doFinal(decryptedBytes);
        return new String(encryptedBytes,"UTF-8");
    }   
}

送信される変数が次の場合、POST メソッドを介してサーバーにメッセージを送信しています。m=encryptedMessage.

何らかの理由で私はいつも

javax.crypto.IllegalBlockSizeException: Input length must be multiple of 8 when decrypting with padded cipher

サーバー側で受信したメッセージを復号化できません..

最初はメッセージが壊れているのではないかと思いましたが、そうではありません..

何か案は ?

更新1:

奇妙なことに、サーバーへの一部のメッセージは適切に復号化され、一部はそのエラーを返します。良いメッセージ:

zuhRpmbtH0xSmv6cnBFkAxaGFmRbDP/97LwF4bcDyhANCTLb4afBzFpP3GI1pGFLok03GRQVCwi81Hsp                                             bCpGtuoIVY9cqWYDzNFgOCx5w2sboR2Qx6oxtTSIFIzj1XadQdk9V8lCxcCVVYEH8vA3tph63wU6qJOo                                             OyROz0OJauLBEiWbn5OUQxJ7Yz9Qc1wzl8z7UQb71v4pswF69c1CM/LWWmAzBDCjlRQ5YIB9wN8mBgoC                                             t8Ngt38XkCg/yRHh0EpXYQfrgP6Ls5I8/FY8BQorMy/le5y2

悪いメッセージ:

cjj7yzW v3NDtbIJXurrrf318DcY PBk2inzSfz qoIaTKns2tWvR7ftOKK30XY VAlXDrQlyTLatgKA                                             S4IkAIK3lXQKNcwPh87CybHrTqD3HWEM3tqkpVWdB7GNmpHYsITTLrWsBvaMeDcXEr/gr9KYSZ0ks0gR                                             z12jHxPiZoSKHdy5nZ4zShHUy/wlkslmjFvA1G8A15nTVBhjBI GWSh54tyBZF113lL pm5eZNkZrqzo                                             RWI2QAjfqNPzCpV0tqd/pEO70vdSLbCYi7V0bVQNW2KpBv3Hj3VOTCP92k62/iQhIY4F VuMo2UTgGWV                                             1fqoelrl/eelAvsZO8YNC5/2KTKw2sDFaTOwW9R12AgeyzOuhkKQQro2Umd0KoiGnYL9AaQ6 T2MBnLK                                             ZyROHh3cvI T9chPlGfmUHbCN2f3pHoF5rb383KpJNjvlnmnwtaEhQYw8TQjj4PLenK24Hpcs4 wO8gu                                             XSrUglFzLIkkwjvsA5AyTHx/jP9AwMSnWjDwco184YQGAePeM8PYy42oMOaw7Pg/3jWFy1uOzFok2LN9                                             RJWv1iyXejh5s9zXoAT3kywICQygK2YTLZNIS1d5lc0H0f15EN6itZhaR0YnslhYGmH1KcNwdMWhBKsf                                             PytWnK0N8AzUVzt4P4mtmGSuaLi2t54J2pv7m7/c6WjTi1/E16rd3QyWkmXrghSshOJNRRwcydlhhTLH                                             drHTEFaXSPZyVFqlaFu4 f5kxiBa6ewglKHe6zbmRyM15Mq3lRj8Ab/RWBd2tgvaEO/vhw

これらのメッセージは両方とも同じ方法で送信され、テストのために System.Out に出力されます。あなたが見ることができるように、悪いメッセージには何らかの理由でスペースがありますが、良いメッセージにはおそらくブロックエラーメッセージが表示されません..それを解決する方法はありますか?

更新 2:

コードを掘り下げた後、私の問題は POST メソッドのパラメーターを解析する関数内にあることがわかりました。私はエンコーディングの専門家だとは言えませんが、Base64 エンコーディングを渡す際に問題があり、POST URLEcoding をスローします。

これは私の解析コードで、URLDecode を取得した後、解読のために Encrypter に送られます。

private void parseQuery(文字列クエリ、HashMap パラメータ) は UnsupportedEncodingException をスローします {

 if (query != null) {
     String pairs[] = query.split("[&]");

     for (String pair : pairs) 
     {
         String param[] = pair.split("[=]");
         String key = null;
         String value = null;
         if (param.length > 0) 
             key = URLDecoder.decode(param[0], "UTF-8");//System.getProperty("file.encoding"));                 

         if (param.length > 1) 
             value = URLDecoder.decode(param[1], "UTF-8");//System.getProperty("file.encoding"));                 

         if (parameters.containsKey(key)) 
         {
             Object obj = parameters.get(key);
             if(obj instanceof List<?>)
             {
                 @SuppressWarnings("unchecked")
                 List<String> values = (List<String>)obj;
                 values.add(value);
             } 
             else if(obj instanceof String) 
             {
                 List<String> values = new ArrayList<String>();
                 values.add((String)obj);
                 values.add(value);
                 parameters.put(key, values);
             }
         } 
         else 
           parameters.put(key, value);                 
     }
 }

}

何か案は ?

4

3 に答える 3

1

たくさんのテストと泣き声の後、うまくいきました:)、私は最初から疑っていたものを見つけました.

URL を介してデータを渡す場合 (POST\GET は何でも)、送信する前にクライアント側で最初に URL エンコードし、処理する前にサーバー側で URL デコードする必要があります。

Java の優れたURLEncoderおよびURLDecoderクラスのおかげで、簡単に実行できます。

//送信前に URL のデータをエンコード - クライアント側 URLEncoder.encode(your_data,charset_name); //charset_name - 「UTF-8」を使用することをお勧めします

//データを受信した後 - 処理のためにデータをデコード - サーバー側 URLDecoder.decode(your_data,charset_name); //charset_name - 「UTF-8」を使用することをお勧めします

于 2013-03-12T10:30:15.627 に答える
0

代替手段を絞り込むには、Oracle/Sun からダウンロードして無制限の強度の JCE ポリシー jar を配置し、JVM の下に配置します。私の Java 暗号化の経験から、暗号化の際に直面する問題の 90% は、JVM/JDK が強力ではあるが制限付きの強度ポリシーで出荷されており、252k 以上のアルゴリズムを使用しようとすると、JVM が起動するという事実に起因します。いくつかの奇妙なエラーをスローします。

于 2014-08-03T14:35:40.043 に答える