2016-03-15 106 views
2

請在將此標記爲重複項之前,請先了解我無法在有關河豚的計算器上找到任何有用的信息。我正在嘗試使用Android Studio對blowfish進行加密和解密。我的加密似乎工作。但是,當我嘗試解密所述字符串時,它實際上更短並且用字符編碼。我對加密非常陌生,不勝感激。河豚加密問題

加密

import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.io.UnsupportedEncodingException; 
import java.security.InvalidKeyException; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 


public class Encryption { 

private String algorithm = "Blowfish/CBC/PKCS5Padding"; 
private SecretKeySpec keySpec; 
private Cipher cipher; 


public void setupForEncryption(String keyString) throws java.security.GeneralSecurityException, UnsupportedEncodingException { 
    byte[] keyData = keyString.getBytes(); 
    keySpec = new SecretKeySpec(keyString.getBytes("UTF-8"), "Blowfish"); 
    cipher = Cipher.getInstance(algorithm); 
} 

public SecretKeySpec getSecretKey() { 
    return keySpec; 
} 

public boolean checkForKeySpec() { 
    if (keySpec != null) { 
     return true; 
    } 
    return false; 
} 

public String encryptString(String inputString) throws java.security.GeneralSecurityException, UnsupportedEncodingException { 
    IvParameterSpec ivSpec = new IvParameterSpec(keySpec.getEncoded()); 
    cipher.init(Cipher.ENCRYPT_MODE, getSecretKey(),ivSpec); 
    byte[] encryptedBytes = cipher.doFinal(inputString.getBytes("UTF-8")); 
    return new String(encryptedBytes); 
} 

解密

import android.util.Base64; 

import java.io.UnsupportedEncodingException; 
import java.security.InvalidAlgorithmParameterException; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 

import javax.crypto.BadPaddingException; 
import javax.crypto.Cipher; 
import javax.crypto.IllegalBlockSizeException; 
import javax.crypto.NoSuchPaddingException; 
import javax.crypto.spec.IvParameterSpec; 
import javax.crypto.spec.SecretKeySpec; 

public class Decryption { 

private SecretKeySpec keySpec; 
private String algorithm = "Blowfish/CBC/PKCS5Padding"; 
private Cipher cipher; 

public void setupForDecryption(String key) throws NoSuchPaddingException, NoSuchAlgorithmException, UnsupportedEncodingException { 
    byte[] keyData = key.getBytes(); 
    keySpec = new SecretKeySpec(key.getBytes("UTF-8"), "Blowfish"); 
    cipher = Cipher.getInstance(algorithm); 
} 

public boolean checkForKeySpec() { 
    if(keySpec != null){ 
     return true; 
    } 
    return false; 
} 

public SecretKeySpec getSecretKey() { 
    return keySpec; 
} 

public String decryptString(String inputString) throws InvalidKeyException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, UnsupportedEncodingException { 
    IvParameterSpec ivSpec = new IvParameterSpec(keySpec.getEncoded()); 
    cipher.init(Cipher.DECRYPT_MODE, getSecretKey(),ivSpec); 
    byte[] decryptedBytes = Base64.decode(inputString,0); 
    String decrypted = new String(decryptedBytes); 
    return decrypted; 
} 
} 
+3

爲什麼要使用像Blowfish這樣十多年前的加密算法? –

+0

河豚,整潔的名字,使用它十年前,舊的算法。目前的標準是AES(高級加密算法),名稱說明了一切。 – zaph

回答

1

你在加密過程中這樣做:

return new String(encryptedBytes); 

其中encryptedBytes可以由任意字節值。通過強制將這些字節轉換爲字符串,實質上就是刪除那些默認編碼中不可打印的字節。

此外,在解密過程中,您忘記了解密(cipher.doFinal(inputString.getBytes("UTF-8")))。我只看到Base64.decode,這是一種編碼而不是加密。

如果要發送字符串,則需要將字節數組編碼爲可打印的字符串,並使用諸如Base64或Hex等編碼。


從字節轉換爲字符串bytes.getBytes("UTF-8")和背面new String(str, "UTF-8")時,始終使用特定的編碼。否則,當默認字符集更改時,您可能會遇到設備之間的不兼容問題。

始終使用CBC模式的隨機IV。它提供了語義安全性。 IV不必是保密的,所以你可以簡單地將它與密文一起發送,並在解密時使用它。將它簡單地加密到密文中是很常見的。