2012-08-13 80 views
0

我下面this tutorial使用3DES加密,我需要作出密碼設置一些變化,所以這裏是我的代碼:TripleDes的加密錯誤

public class TripleDES { 

public static int MAX_KEY_LENGTH = DESedeKeySpec.DES_EDE_KEY_LEN; 
private static String ENCRYPTION_KEY_TYPE = "DESede"; 
private static String ENCRYPTION_ALGORITHM = "DESede/ECB/PKCS7Padding"; 
private final SecretKeySpec keySpec; 
private final static String LOG = "TripleDES"; 

public TripleDES(String passphrase) { 
    byte[] key; 
    try { 
     // get bytes representation of the password 
     key = passphrase.getBytes("UTF8"); 
    } catch (UnsupportedEncodingException e) { 
     throw new IllegalArgumentException(e); 
    } 

    key = padKeyToLength(key, MAX_KEY_LENGTH); 
    key = addParity(key); 
    keySpec = new SecretKeySpec(key, ENCRYPTION_KEY_TYPE); 
} 

// !!! - see post below 
private byte[] padKeyToLength(byte[] key, int len) { 
    byte[] newKey = new byte[len]; 
    System.arraycopy(key, 0, newKey, 0, Math.min(key.length, len)); 
    return newKey; 
} 

// standard stuff 
public byte[] encrypt(String message) throws GeneralSecurityException, UnsupportedEncodingException { 
    byte[] unencrypted = message.getBytes("UTF8"); 
    return doCipher(unencrypted, Cipher.ENCRYPT_MODE); 
} 

public byte[] decrypt(byte[] encrypted) throws GeneralSecurityException { 
    return doCipher(encrypted, Cipher.DECRYPT_MODE); 
} 

private byte[] doCipher(byte[] original, int mode) 
     throws GeneralSecurityException { 
    Cipher cipher = Cipher.getInstance(ENCRYPTION_ALGORITHM); 
    // IV = 0 is yet another issue, we'll ignore it here 
    // IvParameterSpec iv = new IvParameterSpec(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }); 
    cipher.init(mode, keySpec); //, iv); 
    return cipher.doFinal(original); 
} 

// Takes a 7-byte quantity and returns a valid 8-byte DES key. 
// The input and output bytes are big-endian, where the most significant 
// byte is in element 0. 
public static byte[] addParity(byte[] in) { 
    byte[] result = new byte[8]; 

    // Keeps track of the bit position in the result 
    int resultIx = 1; 

    // Used to keep track of the number of 1 bits in each 7-bit chunk 
    int bitCount = 0; 

    // Process each of the 56 bits 
    for (int i = 0; i < 56; i++) { 
     // Get the bit at bit position i 
     boolean bit = (in[6 - i/8] & (1 << (i % 8))) > 0; 

     // If set, set the corresponding bit in the result 
     if (bit) { 
      result[7 - resultIx/8] |= (1 << (resultIx % 8)) & 0xFF; 
      bitCount++; 
     } 

     // Set the parity bit after every 7 bits 
     if ((i + 1) % 7 == 0) { 
      if (bitCount % 2 == 0) { 
       // Set low-order bit (parity bit) if bit count is even 
       result[7 - resultIx/8] |= 1; 
      } 
      resultIx++; 
      bitCount = 0; 
     } 
     resultIx++; 
    } 

    Log.d(LOG, "result: " + result); 
    return result; 
} 
} 

但我在這一行越來越InvalidKeyException異常:

cipher.init(mode, keySpec); 

的logcat:

W/System.err(758): java.security.InvalidKeyException: src.length=8 srcPos=8 dst.length=8 dstPos=0 length=8 
W/System.err(758): at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(JCEBlockCipher.java:584) 
W/System.err(758): at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(JCEBlockCipher.java:631) 
W/System.err(758): at javax.crypto.Cipher.init(Cipher.java:511) 
W/System.err(758): at javax.crypto.Cipher.init(Cipher.java:471) 

我在encrytion新的,所以我PROBA bly忽略了一些東西,但我找不到它是什麼。任何幫助表示讚賞...

+0

您能不能告訴我們cipher.init ()? – KingCronus 2012-08-13 08:43:24

+0

這是在doCipher? – yahya 2012-08-13 08:45:43

回答

0

我找到了解決方案,通過改變這些行:

try { 
    // get bytes representation of the password 
    key = passphrase.getBytes("UTF8"); 
} catch (UnsupportedEncodingException e) { 
    throw new IllegalArgumentException(e); 
} 

key = padKeyToLength(key, MAX_KEY_LENGTH); 
key = addParity(key); 
keySpec = new SecretKeySpec(key, ENCRYPTION_KEY_TYPE); 

到這些:

Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); 
byte[] keyBytes = GetKeyAsBytes(key); 
keySpec = new SecretKeySpec(keyBytes, "DESede"); 

而GetKeyAsBytes方法是這樣的:

public byte[] GetKeyAsBytes(String key) { 
    byte[] keyBytes = new byte[24]; // a Triple DES key is a byte[24] array 

    for (int i = 0; i < key.length() && i < keyBytes.length; i++) 
     keyBytes[i] = (byte) key.charAt(i); 

    return keyBytes; 
} 
0

三重DES需要一個24字節的密鑰,而不是一個8字節的密鑰。

+0

我刪除了這一行:key = addParity(key);現在它給我錯誤的解碼javax.crypto.BadPaddingException:墊塊損壞 – yahya 2012-08-13 09:20:57

+0

哪個安全提供商提供DESede/ECB/PKCS7Padding? ((我的股票JDK7似乎不支持它。)它是否與'「DESede/CBC/NoPadding」'一起工作? – martijno 2012-08-13 10:15:49

+0

BouncyCastleProvider()...我現在關注這個頁面:http://www.java2s但是我想我需要找到一種方法來讓我的關鍵詞在這個頁面上顯示,你能告訴我怎麼做嗎? – yahya 2012-08-13 11:02:22