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

Java 三重DES解密16字节的无效密钥,java,android,encryption,tripledes,Java,Android,Encryption,Tripledes,我有一个android项目,在这个项目中,我从我的web服务中得到一段三重DES加密的文本。我需要三重DES解密 但是,我得到了无效的密钥异常。我的密钥被转换为十六进制格式,我得到一个错误:W/System.err﹕ java.security.InvalidKeyException:DES密钥太长-应该是8字节我发现一个论坛解释十六进制可能导致问题 “DES密钥是56位,通常打包为8个字节,因此它们提供给您的16个字节/字符很可能是密钥的十六进制编码字节。您可以获得十六进制解码器” 因此,我使

我有一个android项目,在这个项目中,我从我的web服务中得到一段三重DES加密的文本。我需要三重DES解密

但是,我得到了无效的密钥异常。我的密钥被转换为十六进制格式,我得到一个错误:
W/System.err﹕ java.security.InvalidKeyException:DES密钥太长-应该是8字节
我发现一个论坛解释十六进制可能导致问题

“DES密钥是56位,通常打包为8个字节,因此它们提供给您的16个字节/字符很可能是密钥的十六进制编码字节。您可以获得十六进制解码器”

因此,我使用

 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;
    }
这是我的解密方法。如果有人能告诉我哪里可能出错,我将不胜感激

 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;
}

我的钥匙是C9AF269DF8A78A06D1216BFFF8F0536A

我已经与客户端进行了检查,并且密钥是正确的,因此相同的密钥正在用于加密

加密代码

public string TripleDESEncrypt(string strClearText,string strKey)
{
字节[]bytClearText;
byte[]bytClearTextChunk=新字节[8];
byte[]bytEncryptedChunk=新字节[8];
int字节数=0;
int-nArrayPosition=0;
字符串加密字符;
字符串StrengthCryptedText=“”;
ArrayList输入=新的ArrayList();
ArrayList输出=新的ArrayList();
TripleDESCryptoServiceProvider tdes=(TripleDESCryptoServiceProvider)TripleDESCryptoServiceProvider.Create();
tdes.Key=HexToByteArray(strKey);
tdes.Mode=CipherMode.ECB;
ICryptoTransform tdesEncrypt=tdes.CreateEncryptor();
bytClearText=ascienceoding.ASCII.GetBytes(strClearText);
BytesCount=bytClearText.Length;
for(int i=0;i

下面是一个14个字符的解密文本示例:12345678901344

可能您必须使用此密码:

public byte[] encTripleDes (String txt, byte [] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidKeySpecException{
    DESedeKeySpec keySpec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
    SecretKey ky = keyfactory.generateSecret(keySpec);

    Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, ky);
    return cipher.doFinal(txt.getBytes("UTF-8"));

}
以及用于解密:

public byte[] uncTripleDes (byte [] encryptedTextBytes, byte [] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidKeySpecException{
    DESedeKeySpec keySpec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
    SecretKey ky = keyfactory.generateSecret(keySpec);

    Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, ky);
    return cipher.doFinal(encryptedTextBytes);

}
看,我在密码实例中使用了一个“PKCS5Padding”

请注意,填充用于为所有块提供相同的大小(例如,如果最后一个块是788而不是1024)

对于创建密钥,在我的解决方案(不是唯一的解决方案)中,我计算sha-256哈希,然后获得Des密钥所需的字节:

bytedKey = Arrays.copyOf(bytedKey, 16 ); // 16 use only first 128 bit. if 32 use only 256
计算哈希:

public byte[] sumCalc (){ 
    String key = "anyKey";
    byte[] hashedKey = null;
    try {
        byte [] byteKey = key.getBytes("UTF-8");
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        hashedKey = md.digest(byteKey);
    }catch (Exception ex){
        System.err.println("Error generant clau" + ex);  
    }
    return hashedKey;
}
最后,只获取Des密钥所需的128字节:

bytedKey = Arrays.copyOf(bytedKey, 16 ); // 16 use only first 128 bit. if 32 use only 256

这是我的解决方案,但不是唯一的

也许您必须使用此密码:

public byte[] encTripleDes (String txt, byte [] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidKeySpecException{
    DESedeKeySpec keySpec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
    SecretKey ky = keyfactory.generateSecret(keySpec);

    Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, ky);
    return cipher.doFinal(txt.getBytes("UTF-8"));

}
以及用于解密:

public byte[] uncTripleDes (byte [] encryptedTextBytes, byte [] key) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, InvalidKeySpecException{
    DESedeKeySpec keySpec = new DESedeKeySpec(key);
    SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("DESede");
    SecretKey ky = keyfactory.generateSecret(keySpec);

    Cipher cipher = Cipher.getInstance("DESede/ECB/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, ky);
    return cipher.doFinal(encryptedTextBytes);

}
看,我在密码实例中使用了一个“PKCS5Padding”

请注意,填充用于为所有块提供相同的大小(例如,如果最后一个块是788而不是1024)

对于创建密钥,在我的解决方案(不是唯一的解决方案)中,我计算sha-256哈希,然后获得Des密钥所需的字节:

bytedKey = Arrays.copyOf(bytedKey, 16 ); // 16 use only first 128 bit. if 32 use only 256
计算哈希:

public byte[] sumCalc (){ 
    String key = "anyKey";
    byte[] hashedKey = null;
    try {
        byte [] byteKey = key.getBytes("UTF-8");
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        hashedKey = md.digest(byteKey);
    }catch (Exception ex){
        System.err.println("Error generant clau" + ex);  
    }
    return hashedKey;
}
最后,只获取Des密钥所需的128字节:

bytedKey = Arrays.copyOf(bytedKey, 16 ); // 16 use only first 128 bit. if 32 use only 256

这是我的解决方案,但不是唯一的

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

什么时候


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

什么时候


将密码实例化为(单)DES密码,使用:

desCipher = Cipher.getInstance("DES/ECB/NoPadding");
desCipher = Cipher.getInstance("DESede/ECB/NoPadding");
但是您的密钥是一个16字节的3Des密钥,因此您得到了错误

DES key too long - should be 8 bytes
尝试使用以下命令将密码实例化为3DES密码:

desCipher = Cipher.getInstance("DES/ECB/NoPadding");
desCipher = Cipher.getInstance("DESede/ECB/NoPadding");

将密码实例化为(单)DES密码,使用:

desCipher = Cipher.getInstance("DES/ECB/NoPadding");
desCipher = Cipher.getInstance("DESede/ECB/NoPadding");
但是您的密钥是一个16字节的3Des密钥,因此您得到了错误

DES key too long - should be 8 bytes
尝试使用以下命令将密码实例化为3DES密码:

desCipher = Cipher.getInstance("DES/ECB/NoPadding");
desCipher = Cipher.getInstance("DESede/ECB/NoPadding");

它有多长?使用什么字符集?没有任何关于钥匙的信息,这只是一个例子。I games.C9AF269DF8A78A06D1216BFFF8F0536A是关键你不能把这个添加到你的问题中吗?顺便问一下,抛出错误的行是什么?@ArtjomB<代码>W/System.err﹕ java.security.InvalidKeyException W/System.err﹕ 在javax.crypto.spec.DESedeKeySpec.
行中抛出错误
KeySpec desKeySpec=new DESedeKeySpec(hexConvert)它有多长?使用了哪些字符集?没有任何关于钥匙的信息,这只是一个例子。I games.C9AF269DF8A78A06D1216BFFF8F0536A是关键你不能把这个添加到你的问题中吗?顺便问一下,抛出错误的行是什么?@ArtjomB<代码>W/System.err﹕ java.security.InvalidKeyException W/System.err﹕ 在javax.crypto.spec.deseKeySpec。
KeySpec des处抛出错误