2016-03-15 4 views
2

Прежде чем вы отметите это как дубликат, поймите, что я не могу найти полезную информацию о stackoverflow о blowfish. Я пытаюсь зашифровать и расшифровать строки с помощью blowfish с помощью 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

Blowfish, опрятное имя, использовавшее его десять лет назад, старый алгоритм. Текущий стандарт - AES (Advanced Encryption Algorithm), имя говорит все. – zaph

ответ

1

Вы делаете это во время шифрования:

return new String(encryptedBytes); 

где encryptedBytes может состоять из любого значения байтов. Заставляя эти байты быть преобразованными в String, вы по существу удаляете те байты, которые не подлежат печати в кодировке по умолчанию.

Кроме того, во время дешифрования вы забыли расшифровать (cipher.doFinal(inputString.getBytes("UTF-8"))). Я вижу только Base64.decode, который является кодировкой, а не шифрованием.

Если вы хотите отправить строки, вам необходимо закодировать массив байтов в печатную строку с кодировками, такими как Base64 или Hex.


Всегда использовать определенную кодировку при преобразовании из байтов в строку bytes.getBytes("UTF-8") и обратно new String(str, "UTF-8"). В противном случае вы можете столкнуться с несовместимостью между устройствами при изменении набора символов по умолчанию.

Всегда используйте случайный режим IV с режимом CBC. Он обеспечивает семантическую безопасность. IV не обязательно должен быть секретным, поэтому вы можете просто отправить его вместе с зашифрованным текстом и использовать его во время дешифрования. Обычно просто префикс шифрованного текста.