Java 三重DES解密16字节的无效密钥
我有一个android项目,在这个项目中,我从我的web服务中得到一段三重DES加密的文本。我需要三重DES解密 但是,我得到了无效的密钥异常。我的密钥被转换为十六进制格式,我得到一个错误: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个字节/字符很可能是密钥的十六进制编码字节。您可以获得十六进制解码器” 因此,我使
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处抛出错误