2012-05-16 122 views
1

我无法解密使用3Des的第三方的值。他们给了我一个密钥,一个加密的值,使用的模式,以及解密的值应该是什么,但到目前为止,我一直无法弄清楚如何从a点到b点。我相信问题与他们给予我的关键有关 - 他们说这是明文密钥,但我认为它仍然需要进一步改变。使用Java解密3Des中的值

下面的代码是是我的初始试图了解如何解密(在这种情况下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); 
    } 

} 
+0

Huzza。那是缺失的环节。 –

0

主要问题似乎是使用包含通过getBytes()转换为字节数组的十六进制数据的字符串。

对于一个十六进制字符串转换成您需要的外部库的字节数组表示,如apache.commons.codec.binary

myEncryptionKey = "1032FD2CD64A9D7FA4D061F76B04BFEA"; 
arrayBytes = Hex.decodeHex(myEncryptionKey.toCharArray());