2009-10-29 131 views

回答

2

從舊的代碼:

public void testSymCypher(SecretKey k, String str) 
     throws BadPaddingException, IllegalBlockSizeException, 
     InvalidAlgorithmParameterException, InvalidKeyException, 
     NoSuchAlgorithmException, NoSuchPaddingException 
{ 
    Cipher cip = Cipher.getInstance("DESede/CBC/PKCS5Padding"); 
    cip.init(Cipher.ENCRYPT_MODE,k); 
    byte[] ciphered = cip.doFinal(str.getBytes()); 
    byte iv[] = cip.getIV(); 

    // printing the ciphered string 
    printHexadecimal(ciphered); 

    IvParameterSpec dps = new IvParameterSpec(iv); 
    cip.init(Cipher.DECRYPT_MODE,k,dps); 
    byte[] deciphered = cip.doFinal(ciphered); 

    // printing the deciphered string 
    printHexadecimal(deciphered); 
} 

比DESede的其他使用通知中的Java JDK可用6:

  • DESede/CBC/NoPadding(168)
  • DESede/CBC/PKCS5Padding(168)

還有ECB模式下可用(但要carreful不使用它的兩倍!),你不需要在這種情況下,使用第四部分:

  • DESede/ECB/NoPadding(168)
  • DESede/ECB/PKCS5Padding(168)

要生成DESede鍵:

KeyGenerator generatorDes = KeyGenerator.getInstance("DESede"); 
    SecretKey skaes = generatorDes.generateKey(); 

最後,我從推薦閱讀SUN如果this document你需要對Java和加密工作

+0

此代碼給了我一個java.security.InvalidKeyException:無效密鑰長度:8個字節\t在com.sun.crypto.provider.DESedeCipher.engineGetKeySize(DashoA13 * ..) – ScArcher2 2009-10-29 19:20:45

+0

我想這是因爲我犯了一個錯誤用的KeyGenerator :它是DESede而不是DES。 如果您使用自己的密鑰,請檢查您的密鑰大小(它似乎與您使用的3DES密鑰的種類有關,因爲我不太瞭解它,請參閱3DES的維基百科頁面)。 – Kartoch 2009-10-29 21:16:03

1

我們使用基於密碼的DES加密這個小幫手類從字符串到十六進制字符串和背部 - 不知道如何得到這個使用3DES工作雖然:

import java.security.spec.KeySpec; 

import javax.crypto.Cipher; 
import javax.crypto.SecretKey; 
import javax.crypto.SecretKeyFactory; 
import javax.crypto.spec.PBEKeySpec; 
import javax.crypto.spec.PBEParameterSpec; 

public class DesHelper { 
    private static org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(DesHelper.class); 

    static final byte[] SALT = { (byte) 0x09, /* snip - randomly chosen but static salt*/ }; 
    static final int ITERATIONS = 11; 

    private Cipher _ecipher; 
    private Cipher _dcipher; 

    public DesHelper(final String passphrase) { 
     try { 
      final PBEParameterSpec params = new PBEParameterSpec(SALT, ITERATIONS); 

      final KeySpec keySpec = new PBEKeySpec(passphrase.toCharArray()); 
      final SecretKey key = SecretKeyFactory.getInstance("PBEWithMD5AndDES") 
        .generateSecret(keySpec); 

      _ecipher = Cipher.getInstance(key.getAlgorithm()); 
      _dcipher = Cipher.getInstance(key.getAlgorithm()); 
      _ecipher.init(Cipher.ENCRYPT_MODE, key, params); 
      _dcipher.init(Cipher.DECRYPT_MODE, key, params); 

     } catch (final Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public String encrypt(final String string) { 
     try { 
      // Encode the string into bytes using utf-8 
      final byte[] bytes = string.getBytes("UTF-8"); 

      // Encrypt 
      final byte[] enc = _ecipher.doFinal(bytes); 

      // Encode bytes to base64 to get a string 
      return bytesToHex(enc); 
     } catch (final Exception e) { 
      throw new RuntimeException(e); 
     } 
    } 

    public String decrypt(final String str) { 
     try { 
      // Decode base64 to get bytes 
      final byte[] dec = hexToBytes(str); 

      // Decrypt 
      final byte[] utf8 = _dcipher.doFinal(dec); 

      // Decode using utf-8 
      return new String(utf8, "UTF8"); 
     } catch (final Exception e) { 
      log.info("decrypting string failed: " + str + " (" + e.getMessage() + ")"); 
      return null; 
     } 
    } 

    private static String bytesToHex(final byte[] bytes) { 
     final StringBuilder buf = new StringBuilder(bytes.length * 2); 
     for (final byte b : bytes) { 
      final String hex = Integer.toHexString(0xff & b); 
      if (hex.length() == 1) { 
       buf.append("0"); 
      } 
      buf.append(hex); 
     } 
     return buf.toString(); 
    } 

    private static byte[] hexToBytes(final String hex) { 
     final byte[] bytes = new byte[hex.length()/2]; 
     for (int i = 0; i < bytes.length; i++) { 
      bytes[i] = (byte) Integer.parseInt(hex.substring(i * 2, i * 2 + 2), 16); 
     } 
     return bytes; 
    } 
} 

你會使用這個類是這樣的:

public static void main(final String[] args) { 
    final DesHelper h = new DesHelper("blabla"); 
    System.out.println(h.decrypt(h.encrypt("foobar"))); 
} 
0

您也可以考慮使用流密碼(例如,3DES塊加密頂部的OFB或CTR模式),以便您不必處理將字符串填充到密碼塊大小的倍數。