0

サーバーでフレームを復号化する必要があります。暗号化されたフレームは、ソケットの GPRS を介してクライアント デバイスから送信されます。暗号化は、「TripleDes」と特定のキーで行われます。同じアルゴリズムとキーは、サーバー側で使用しています。フレームは、16 進数と ASCII 文字列の組み合わせです。問題は、このフレームを復号化するとエラーが発生することです:

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

そして、バイト配列にゼロを埋め込むと

temparray[87] = 00;

エラーが発生します:

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

以下は私のコードです:

if ((len = inputStream.read(mainBuffer)) > -1) {
                totalLength = len;
            }
if (totalLength > 0) {
                byteToAscii = function.byteToAscii(mainBuffer, totalLength);
            }
if (byteToAscii.length() > 0) {
                completeHexString = function.stringToHex(byteToAscii);               
                debugInfo = "FRAME RECV.=" + completeHexString;
/* FRAME RECV.=41ed34a41a9de6d270aa1e1464527e88c8bee66a00cfb308f60c105de81db0f1ce43d8c0b9bc4e8070b5ab8d4d3650b55d23223fc687bb1485945bc3228e9707a7aecda9f90657e0ac009571c6469c58a2cd9793cc433ccb5993f2*/
            }
byte[] key = new byte[]{31, 30, 31, 36, 32, 11, 11, 11, 22, 26, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30};
myKeySpec = new DESedeKeySpec(key);
mySecretKeyFactory = SecretKeyFactory.getInstance("TripleDES");
dekey = mySecretKeyFactory.generateSecret(myKeySpec);
byte[] zeros = {0, 0, 0, 0, 0, 0, 0, 0};
IvParameterSpec iv = new IvParameterSpec(zeros);
Cipher c = Cipher.getInstance("TripleDES/CBC/PKCS5Padding");
c.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decordedValue = new BASE64Decoder().decodeBuffer(completeHexString);
byte[] decValue = c.doFinal(decordedValue);
String decryptedValue = new String(decValue);
System.out.println("decryptedValue= " + decryptedValue);

コード内で使用している関数は次のとおりです。

public String stringToHex(String base) {
        StringBuffer buffer = new StringBuffer();
        int intValue = 0;
        for (int x = 0; x < base.length(); x++) {
            intValue = base.charAt(x);
            String hex = Integer.toHexString(intValue);
            if (hex.length() == 1) {
                buffer.append("0" + hex + "");
            } else {
                buffer.append(hex + "");
            }
        }
        return buffer.toString();
    }
public String byteToAscii(byte[] b, int length) {
        String returnString = "";
        for (int i = 0; i < length; i++) {
            returnString += (char) (b[i] & 0xff);
        }
        return returnString;
    }

私はJava暗号化が初めてです。方法を教えてください。前もって感謝します。

4

4 に答える 4

1

PKCS5パディングバイト値は、パディングバイト数である必要があります。たとえば、パディングするバイトが5バイトある場合、パディングはになります05 05 05 05 05。パディングするバイトが2バイトある場合、パディングはになります02 02

于 2012-05-02T14:19:07.397 に答える
0

temparray[88]89バイト目にアクセスしているということですが、1バイト多すぎませんか?

私はあなたが持っているべきだと思います:

temparray[87] = 00; // this is byte number 88

そして、

temparray[88] = 00; // this is byte number 89
于 2012-05-02T11:44:18.280 に答える
0

エラー メッセージは、最後のブロックの長さに問題があることを示しています。

入力フレームを見ると、その長さは 8 の倍数ではありません。完全な 8 バイト ブロックが 11 個、4 バイトの半分のブロックが 1 個、合計 92 バイトになります。復号化を試みる前に、暗号化されていないものを削除する必要がありますか? 完全なメッセージが届きましたか?

また、ある時点でバッファーを Hex としてエンコードし、後の時点で Base-64 としてデコードしていることにも気付きました。それはおそらくあなたが期待しているものをあなたに与えないでしょう. 長さの問題も説明できます。16 進数の 4 文字は 2 バイトですが、Base-64 の 4 文字は 3 バイトです。

于 2012-05-02T16:19:59.707 に答える
0

CipherInputStreamCipherOutputStreamを試してみませんか? そうすれば、パディングを忘れることができます。

于 2012-05-02T11:41:53.303 に答える