java - Blowfish 加密问题

标签 java android encryption

在将此标记为重复之前,请理解我在 stackoverflow 上找不到任何关于河豚的有用信息。我正在尝试使用 Android Studio 使用河豚加密和解密字符串。我的加密似乎有效。但是当我尝试解密所述字符串时,它明显更短并且用字符编码。我对加密非常陌生,非常感谢任何帮助。

加密

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;
}
}

最佳答案

你在加密期间这样做:

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 不必是 secret 的,因此您可以简单地将它与密文一起发送并在解密过程中使用它。简单地将其作为密文的前缀是很常见的。

关于java - Blowfish 加密问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36002834/

相关文章:

android - 如何以编程方式为 ImageView 设置动画

android - 如何让 LibGDX gradled eclipse 项目在 AIDE(Android IDE 应用程序)上工作

Java:DES/ECB 加密始终产生相同的密文

java - Tomcat 8 DIGEST 身份验证不断要求输入密码

java - 删除包含特定单词的 jsonnode

java - 使用 MapBox 将多个 GeoJSON 源添加到同一图层

python - AES 加密存在问题。无法用正确的 key 解密

c++ - 可以从 ByteQueue 中抽取数据的自定义源

java - 在java中选择正确的引擎

java - 从字符串数组中删除空值的最佳方法