我无法解密使用3Des的第三方的值。他们给了我一个密钥,一个加密的值,使用的模式,以及解密的值应该是什么,但到目前为止,我一直无法弄清楚如何从a点到b点。我认为问题与他们给我的关键有关 - 他们说这是明文密钥,但我认为还需要以某种方式进一步改变。
以下代码是我最初尝试解释如何解密该值的示例(在这种情况下为AC9C5A46A63FC9EA)
任何见解都将不胜感激。
import java.security.spec.KeySpec;
import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
public class TripleDes2 {
private static final String UNICODE_FORMAT = "UTF8";
private static final String DESEDE_ENCRYPTION_SCHEME = "DESede";
private static final String CIPHER_ALG = "DESede/ECB/Nopadding"; //assuming no padding
private KeySpec ks;
private SecretKeyFactory skf;
private Cipher cipher;
private byte[] arrayBytes;
private String myEncryptionKey;
private SecretKey key;
public static void main(String args []) throws Exception {
TripleDes2 td= new TripleDes2();
String decrypted = td.decrypt("AC9C5A46A63FC9EA");
System.out.println("expecting: 04286EDDFDEA6BD7");
System.out.println("found: " + decrypted);
}
public TripleDes2() throws Exception {
myEncryptionKey = "1032FD2CD64A9D7FA4D061F76B04BFEA";
arrayBytes = myEncryptionKey.getBytes(UNICODE_FORMAT);
ks = new DESedeKeySpec(arrayBytes);
skf = SecretKeyFactory.getInstance(DESEDE_ENCRYPTION_SCHEME);
cipher = Cipher.getInstance(CIPHER_ALG);
key = skf.generateSecret(ks);
}
public String decrypt(String encryptedString) {
String decryptedText=null;
try {
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] encryptedText = encryptedString.getBytes();
byte[] plainText = cipher.doFinal(encryptedText);
decryptedText= new String(plainText);
} catch (Exception e) {
e.printStackTrace();
}
return decryptedText;
}
}
答案 0 :(得分:2)
你使用SecretKeyFactory
等使它变得比你需要的更复杂。但主要的问题是你没有正确地转换十六进制数字。
class TripleDES
{
private final String key;
public static void main(String... args)
throws Exception
{
TripleDES td = new TripleDES("1032FD2CD64A9D7FA4D061F76B04BFEA");
String decrypted = td.decrypt("AC9C5A46A63FC9EA");
System.out.println("expecting: 04286EDDFDEA6BD7");
System.out.println("found: " + decrypted);
}
TripleDES(String key)
{
this.key = key;
}
public String decrypt(String input)
throws Exception
{
byte[] tmp = h2b(this.key);
byte[] key = new byte[24];
System.arraycopy(tmp, 0, key, 0, 16);
System.arraycopy(tmp, 0, key, 16, 8);
Cipher cipher = Cipher.getInstance("DESede/ECB/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, new SecretKeySpec(key, "DESede"));
byte[] plaintext = cipher.doFinal(h2b(input));
return b2h(plaintext);
}
private static byte[] h2b(String hex)
{
if ((hex.length() & 0x01) == 0x01)
throw new IllegalArgumentException();
byte[] bytes = new byte[hex.length() / 2];
for (int idx = 0; idx < bytes.length; ++idx) {
int hi = Character.digit((int) hex.charAt(idx * 2), 16);
int lo = Character.digit((int) hex.charAt(idx * 2 + 1), 16);
if ((hi < 0) || (lo < 0))
throw new IllegalArgumentException();
bytes[idx] = (byte) ((hi << 4) | lo);
}
return bytes;
}
private static String b2h(byte[] bytes)
{
char[] hex = new char[bytes.length * 2];
for (int idx = 0; idx < bytes.length; ++idx) {
int hi = (bytes[idx] & 0xF0) >>> 4;
int lo = (bytes[idx] & 0x0F);
hex[idx * 2] = (char) (hi < 10 ? '0' + hi : 'A' - 10 + hi);
hex[idx * 2 + 1] = (char) (lo < 10 ? '0' + lo : 'A' - 10 + lo);
}
return new String(hex);
}
}
答案 1 :(得分:0)
主要问题似乎是使用包含十六进制数据的字符串,这些数据通过getBytes()转换为字节数组。
要将十六进制字符串转换为其字节数组表示形式,您需要一个外部库,例如apache.commons.codec.binary:
myEncryptionKey = "1032FD2CD64A9D7FA4D061F76B04BFEA";
arrayBytes = Hex.decodeHex(myEncryptionKey.toCharArray());