java - 16字节三重DES解密无效 key

标签 java android encryption tripledes

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

但是,我收到无效的关键异常。我的 key 已转换为十六进制格式,并且出现错误:W/System.err:java.security.InvalidKeyException:DES key 太长 - 应该是8字节我发现 here 一个论坛解释十六进制可能导致问题

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

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

 private static byte[] hexStringtoByteArray(String hex){
        int len = hex.length();

        byte [] data = new byte[len/2];
        for(int i=0; i<len;i+=2){
            data[i/2] = (byte)((Character.digit(hex.charAt(i), 16)<<4) + Character.digit(hex.charAt(i+1),16));
        }
        return data;
    }

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

W/System.err﹕ java.security.InvalidKeyException
W/System.err﹕ at javax.crypto.spec.DESedeKeySpec.

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

 public String DesDecryptPin(String pin, String encryptKey) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException, UnsupportedEncodingException {

    String UNICODE_FORMAT = "UTF8";
    String decryptedPinText = null;

    byte[] hexConvert = hexStringtoByteArray(encryptKey);

    SecretKey desKey = null;
    KeySpec desKeySpec = new DESedeKeySpec(hexConvert); // Exception HERE
    Cipher desCipher;
    SecretKeyFactory skf = SecretKeyFactory.getInstance("DESede");
    desCipher = Cipher.getInstance("DES/ECB/NoPadding");
    try {
        desKey = skf.generateSecret(desKeySpec);
    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    }

    desCipher.init(Cipher.DECRYPT_MODE, desKey);
    byte[] decryptPin = desCipher.doFinal(pin.getBytes());
    decryptedPinText = new String(decryptPin, "UTF-8");

    return decryptedPinText;
}

我的 key 是 C9AF269DF8A78A06D1216BFFF8F0536A。

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

加密代码

 public string TripleDESEncrypt(string strClearText, string strKey)
    {
        byte[] bytClearText;
        byte[] bytClearTextChunk = new byte[8];
        byte[] bytEncryptedChunk = new byte[8];
        int BytesCount = 0;
        int nArrayPosition = 0;
        string strEncryptedChar;
        string strEncryptedText = "";

        ArrayList Input = new ArrayList();
        ArrayList Output = new ArrayList();

        TripleDESCryptoServiceProvider tdes = (TripleDESCryptoServiceProvider)TripleDESCryptoServiceProvider.Create();

        tdes.Key = HexToByteArray(strKey);
        tdes.Mode = CipherMode.ECB;

        ICryptoTransform tdesEncrypt = tdes.CreateEncryptor();

        bytClearText = ASCIIEncoding.ASCII.GetBytes(strClearText);
        BytesCount = bytClearText.Length;

        for (int i = 0; i < BytesCount; i++)
        {
            if (nArrayPosition == 8)
            {
                Input.Add(bytClearTextChunk);
                bytClearTextChunk = new byte[8];
                nArrayPosition = 0;
            }
            bytClearTextChunk[nArrayPosition] = bytClearText[i];
            nArrayPosition++;
        }

        if (nArrayPosition != 0)
            Input.Add(bytClearTextChunk);


        foreach (byte[] Cbyte in Input)
        {
            tdesEncrypt.TransformBlock(Cbyte, 0, 8, bytEncryptedChunk, 0);
            Output.Add(bytEncryptedChunk);
            bytEncryptedChunk = null;
            bytEncryptedChunk = new byte[8];
        }


        foreach (byte[] Cbyte in Output)
        {
            foreach (byte BByte in Cbyte)
            {
                strEncryptedChar = BByte.ToString("X");
                strEncryptedChar = strEncryptedChar.PadLeft(2, Convert.ToChar("0"));
                strEncryptedText += strEncryptedChar;
            }
        }

        return strEncryptedText;
    }

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

最佳答案

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

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

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

什么时候

hexConvert := K1 || K2

关于java - 16字节三重DES解密无效 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29671427/

相关文章:

java - 配置 W3C 的 Unicorn 以使用代理服务器

Java Swing (BoxLayout) 对齐问题

java - Tomcat 7 上的 HTML5 服务器发送事件 Servlet 缓冲事件直到套接字关闭

android - 哪些文件可以共享 Android 应用程序源代码

c - 使用指针加密字符串的函数

linux - OpenSSL:使用带有 SHA1 加密的 64 位 DSA 创建公钥/私钥对时遇到问题

java - BouncycaSTLe X509 证书链生成,具有有效的根证书 :unknown object in getInstance

java - 从 Java 到 Excel 的空单元格

android - Appium中Android中的Imageview Src路径

android - Android中的JDBC连接