Android Studio上的Blowfish用于加密/解密



我在这里几乎搜索了有关此主题的所有主题,但我仍然不知道怎么了。我在Android应用程序上创建了3个EditTextEditText您将密钥/密码插入加密和解密; EditText2在其中显示加密文本; EditText3在其中显示解密文本。

由于它仍然是早期测试,因此我将消息或字符串放在应用中的变量中。

问题在于加密给出了类似Blowfish算法的东西,因此没有问题(以2 ==结束,所以我认为它正确地工作了)。我还尝试在解密前解码字符串或使用加密的RAW byte[],而没有任何好结果。解密不会回馈原始的字符串文本,而是提供比加密文本更大的东西。我对洪水的模式不偏爱,所以我开始轻松地开始使用blowfish/cfb/nopadding。

str_keystr2str3暂时宣布为公开。str2将设置EditText2字段的文本,str3将设置EditText3字段的文本。输出的一个示例:从应用程序生成的输出的示例

这是代码:

public void encrypt(){
    //encrypt
    EditText mEdit = (EditText)findViewById(R.id.editText);
    str_key = (String) mEdit.getText().toString();
    int iterationCount = 1000;
    int keyLength = 256;
    int saltLength = keyLength / 8; 
    SecureRandom random = new SecureRandom();
    byte[] salt = new byte[saltLength];
    random.nextBytes(salt);
    KeySpec keySpec = new PBEKeySpec(str_key.toCharArray(), salt,
            iterationCount, keyLength);
    SecretKeyFactory keyFactory = null;
    try {
        keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    byte[] keyBytes = new byte[0];
    try {
        keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
    } catch (InvalidKeySpecException e) {
        e.printStackTrace();
    }
    SecretKey key = new SecretKeySpec(keyBytes, "Blowfish");
    Cipher cipher = null;
    try {
        cipher = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
        e.printStackTrace();
    }
    if ( cipher == null || key == null) {
        //throw new Exception("Invalid key or cypher");
        str2="error";
    }
    else {
        byte[] iv = new byte[cipher.getBlockSize()];
        random.nextBytes(iv);
        IvParameterSpec ivParams = new IvParameterSpec(iv);
        try {
            cipher.init(Cipher.ENCRYPT_MODE, key,ivParams);
        } catch (InvalidKeyException | InvalidAlgorithmParameterException e) {
            e.printStackTrace();
        }

        try {
            raw = cipher.doFinal(message.getBytes("UTF-8"));
        } catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        str2 = Base64.encodeToString(raw,Base64.DEFAULT);
    }

}

这是解密函数:

    public void decrypt(){
          int iterationCount = 1000;
          int keyLength = 256;
          int saltLength = keyLength / 8; 
          SecureRandom random = new SecureRandom();
          byte[] salt = new byte[saltLength];
          random.nextBytes(salt);
          KeySpec keySpec = new PBEKeySpec(str_key.toCharArray(), salt,  iterationCount, keyLength);
          SecretKeyFactory  keyFactory = null;
          try {
               keyFactory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
              } catch (NoSuchAlgorithmException e) {
                 e.printStackTrace();
              }
              byte[] keyBytes = new byte[0];
              try {
                keyBytes = keyFactory.generateSecret(keySpec).getEncoded();
                } catch (InvalidKeySpecException e) {
                  e.printStackTrace();
                }
              SecretKey key = new SecretKeySpec(keyBytes, "Blowfish");

    Cipher cipher2 = null;
    try {
        cipher2 = Cipher.getInstance("Blowfish/CBC/PKCS5Padding"); 
    } catch (NoSuchAlgorithmException | NoSuchPaddingException e) {
        e.printStackTrace();
    }
    iv = new byte[cipher2.getBlockSize()];
    random.nextBytes(iv);
    IvParameterSpec ivSpec = new IvParameterSpec(iv);
    try {
        cipher2.init(Cipher.DECRYPT_MODE, key, ivSpec );
    } catch (InvalidKeyException  | InvalidAlgorithmParameterException e) {
        e.printStackTrace();
    }
    byte[] decryptedBytes = null;
    byte[] app= Base64.decode(str2,Base64.DEFAULT);
    try {
        decryptedBytes = cipher2.doFinal(app);
    } catch (IllegalBlockSizeException | BadPaddingException  e) {
        e.printStackTrace();
    }

    str3 = Base64.encodeToString(decryptedBytes,Base64.DEFAULT);
}

您将加密结果编码为base64,但是当您解密时,您将占据base64的普通字节。取而代之的是Base64首先解码以获取Ciphertext的实际字节阵列,然后解密。

您还直接从UTF8字节阵列中得出密钥,这是一种非常糟糕的方法。您应该使用KDF。PBKDF2是这里最常用的。

产生静脉输液的方式(根本不产生一个)也很差。它应随机生成并预添加到密文。它不需要秘密,只是无法预测。

最后,您根本不使用HMAC,因此任何人都可以更改密文,并且您不知道。

最新更新