16字节三重DES解密无效密钥

DJ-*_*DOO 1 java encryption android tripledes

我有一个 Android 项目,其中从我的 Web 服务获取 Triple DES 加密的文本片段。我需要 Triple DES 解密。

\n\n

但是,我收到无效的关键异常。我的密钥已转换为十六进制格式,但出现错误:我在这里W/System.err\xef\xb9\x95 java.security.InvalidKeyException: DES key too long - should be 8 bytes找到一个论坛解释十六进制可能会导致问题

\n\n

“DES 密钥是 56 位,通常封装在 8 个字节中,因此他们给您的 16 个字节/字符很可能是密钥的十六进制编码字节。您可以获得十六进制解码器”

\n\n

所以我使用将十六进制字符串转换为字节数组

\n\n
 private static byte[] hexStringtoByteArray(String hex){\n        int len = hex.length();\n\n        byte [] data = new byte[len/2];\n        for(int i=0; i<len;i+=2){\n            data[i/2] = (byte)((Character.digit(hex.charAt(i), 16)<<4) + Character.digit(hex.charAt(i+1),16));\n        }\n        return data;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

并将其传递给密码,我得到一个错误:

\n\n
W/System.err\xef\xb9\x95 java.security.InvalidKeyException\nW/System.err\xef\xb9\x95 at javax.crypto.spec.DESedeKeySpec.\n
Run Code Online (Sandbox Code Playgroud)\n\n

这是我的解密方法。如果有人能指出我可能出错的地方,我将不胜感激。

\n\n
 public String DesDecryptPin(String pin, String encryptKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {\n\n    String UNICODE_FORMAT = "UTF8";\n    String decryptedPinText = null;\n\n    byte[] hexConvert = hexStringtoByteArray(encryptKey);\n\n    SecretKey desKey = null;\n    KeySpec desKeySpec = new DESedeKeySpec(hexConvert); // Exception HERE\n    Cipher desCipher;\n    SecretKeyFactory skf = SecretKeyFactory.getInstance("DESede");\n    desCipher = Cipher.getInstance("DES/ECB/NoPadding");\n    try {\n        desKey = skf.generateSecret(desKeySpec);\n    } catch (InvalidKeySpecException e) {\n        e.printStackTrace();\n    }\n\n    desCipher.init(Cipher.DECRYPT_MODE, desKey);\n    byte[] decryptPin = desCipher.doFinal(pin.getBytes());\n    decryptedPinText = new String(decryptPin, "UTF-8");\n\n    return decryptedPinText;\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

我的密钥是C9AF269DF8A78A06D1216BFFF8F0536A。

\n\n

我已与客户端核实,密钥是正确的,因此使用相同的密钥进行加密。

\n\n

加密代码

\n\n
 public string TripleDESEncrypt(string strClearText, string strKey)\n    {\n        byte[] bytClearText;\n        byte[] bytClearTextChunk = new byte[8];\n        byte[] bytEncryptedChunk = new byte[8];\n        int BytesCount = 0;\n        int nArrayPosition = 0;\n        string strEncryptedChar;\n        string strEncryptedText = "";\n\n        ArrayList Input = new ArrayList();\n        ArrayList Output = new ArrayList();\n\n        TripleDESCryptoServiceProvider tdes = (TripleDESCryptoServiceProvider)TripleDESCryptoServiceProvider.Create();\n\n        tdes.Key = HexToByteArray(strKey);\n        tdes.Mode = CipherMode.ECB;\n\n        ICryptoTransform tdesEncrypt = tdes.CreateEncryptor();\n\n        bytClearText = ASCIIEncoding.ASCII.GetBytes(strClearText);\n        BytesCount = bytClearText.Length;\n\n        for (int i = 0; i < BytesCount; i++)\n        {\n            if (nArrayPosition == 8)\n            {\n                Input.Add(bytClearTextChunk);\n                bytClearTextChunk = new byte[8];\n                nArrayPosition = 0;\n            }\n            bytClearTextChunk[nArrayPosition] = bytClearText[i];\n            nArrayPosition++;\n        }\n\n        if (nArrayPosition != 0)\n            Input.Add(bytClearTextChunk);\n\n\n        foreach (byte[] Cbyte in Input)\n        {\n            tdesEncrypt.TransformBlock(Cbyte, 0, 8, bytEncryptedChunk, 0);\n            Output.Add(bytEncryptedChunk);\n            bytEncryptedChunk = null;\n            bytEncryptedChunk = new byte[8];\n        }\n\n\n        foreach (byte[] Cbyte in Output)\n        {\n            foreach (byte BByte in Cbyte)\n            {\n                strEncryptedChar = BByte.ToString("X");\n                strEncryptedChar = strEncryptedChar.PadLeft(2, Convert.ToChar("0"));\n                strEncryptedText += strEncryptedChar;\n            }\n        }\n\n        return strEncryptedText;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

以下是包含 14 个字符的解密文本的示例:12345678901234

\n

Art*_* B. 5

DES 期望一个 8 字节密钥(带奇偶校验)。因此 Triple DES 需要 24 字节密钥(带奇偶校验)。由于您只有 16 字节密钥,因此您必须复制其中的一部分才能获得最终密钥。通常第一个和最后 8 个字节是相同的。您可以尝试两种变体:

byte[] tdesKey = new byte[24];
System.arraycopy(hexConvert, 0, tdesKey, 0, 16);
System.arraycopy(hexConvert, 0, tdesKey, 16, 8);
// tdesKey := K1 || K2 || K1
Run Code Online (Sandbox Code Playgroud)

或者

byte[] tdesKey = new byte[24];
System.arraycopy(hexConvert, 8, tdesKey, 0, 8);
System.arraycopy(hexConvert, 0, tdesKey, 8, 16);
// tdesKey := K2 || K1 || K2
Run Code Online (Sandbox Code Playgroud)

什么时候

hexConvert := K1 || K2
Run Code Online (Sandbox Code Playgroud)