繁体   English   中英

Android Studio上的河豚进行加密/解密

[英]Blowfish on android studio for encryption/decryption

我在这里搜索了几乎所有与此主题相关的主题,但仍然无法弄清问题所在。 我已经在Android应用程序上创建了3个EditTextEditText ,您在其中插入密钥/密码进行加密和解密; EditText2中显示加密文本; EditText3显示解密后的文本。

由于这仍是早期测试,因此我已将消息或字符串作为变量放入应用程序中的Crypt中。

问题是加密提供了类似河豚算法的东西,所以那里没有问题(它以2 ==结尾,所以我认为它工作正常)。 我也曾尝试在解密之前对字符串进行解码,或者使用加密中的raw byte[]却没有任何好的结果。 解密不会返回原始的String文本,而是提供比加密文本更大的内容。 我对河豚的模式没有偏爱,所以我开始做河豚/ 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解码,以获取密文的实际字节数组,然后再对其进行解密。

您还直接从UTF8字节数组派生密钥,这是一种非常差的方法。 您应该改用KDF。 PBKDF2是此处最常用的。

生成IV(完全不生成IV)的方式也很差。 它应该是随机生成的,并以密文开头。 它不需要是秘密的,只是不可预测的。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM