0

我必须在我的服务器上解密一个帧。加密帧来自客户端设备,通过套接字上的 GPRS。加密是使用“TripleDes”和给定的密钥完成的。我使用 n 服务器端的算法和密钥相同。frame 是 Hex 和 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. 它有两个字节要填充,填充将是02 02.

于 2012-05-02T14:19:07.397 回答
0

temparray[88]表示您正在访问第 89 个字节,是不是太多了?

我认为你应该只有:

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

并删除

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

你为什么不试试CipherInputStreamCipherOutputStream?这样你就可以忘记填充。

于 2012-05-02T11:41:53.303 回答
0

您的错误消息告诉您最后一个块的长度有问题:“使用填充密码解密时输入长度必须是 8 的倍数”

查看您的输入帧,它的长度不是 8 的倍数。我计算了 11 个完整的 8 字节块和 4 个字节的半块,总共 92 个字节。您是否应该在尝试解密之前删除一些未加密的内容?完整的消息到达了吗?

我还注意到,有一次您将缓冲区编码为十六进制,稍后您将其解码为 Base-64。这可能不会给你你所期望的。它也可以解释长度问题。十六进制的四个字符是两个字节,而 Base-64 的四个字符是三个字节。

于 2012-05-02T16:19:59.707 回答