【问题标题】:Getting "EVP_DecryptFinal_ex:wrong final block length" during decryption在解密期间获取“EVP_DecryptFinal_ex:错误的最终块长度”
【发布时间】:2014-05-02 21:54:01
【问题描述】:

我按照本教程在 android/java 中加密和解密简单字符串:

https://stackoverflow.com/questions/4319496/how-to-encrypt-and-decrypt-data-in-java 我做了一个密码学课:

public class Cryptography {

    public static SecretKey generateKey() throws NoSuchAlgorithmException {
        MessageDigest digest = MessageDigest.getInstance("SHA");
        digest.update("BhLKTyLoP YroUsRQT".getBytes());
        return new SecretKeySpec(digest.digest(), 0, 16, "AES");
    }

    public static byte[] encrypt(String message, SecretKey key) throws NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, NoSuchPaddingException, InvalidKeyException, UnsupportedEncodingException {
        Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
        aes.init(Cipher.ENCRYPT_MODE, key);
        return aes.doFinal(message.getBytes());
    }

    public static String decrypt(byte[] cipherText, SecretKey key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
        Cipher aes = Cipher.getInstance("AES/ECB/PKCS5Padding");
        aes.init(Cipher.DECRYPT_MODE, key);
        return new String(aes.doFinal(cipherText));
    }

}

我能够加密方法并给了我这个:

Encrypted username: [B@52aff408 
Encrypted password: [B@52aff6d8

但是,当我使用解密时:

SecretKey secret = Cryptography.generateKey();
Log.d("encryption", "Decrypted username: " + Cryptography.decrypt(encryptedUsername.getBytes(),secret)
                                + " Decrypted password: " +  Cryptography.decrypt(encyptedPassword.getBytes(),secret));

它给了我错误:

03-25 15:22:23.461    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ java.lang.RuntimeException: error:0606506D:digital envelope routines:EVP_DecryptFinal_ex:wrong final block length
03-25 15:22:23.461    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.NativeCrypto.EVP_CipherFinal_ex(Native Method)
03-25 15:22:23.461    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:398)
03-25 15:22:23.461    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at org.apache.harmony.xnet.provider.jsse.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:434)
03-25 15:22:23.461    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at javax.crypto.Cipher.doFinal(Cipher.java:1111)
03-25 15:22:23.461    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at com.sblive.utils.Cryptography.decrypt(Cryptography.java:28)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at com.sblive.aufschoolbliz.GradeBookFragment$2.onClick(GradeBookFragment.java:99)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at android.view.View.performClick(View.java:4240)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at android.view.View$PerformClick.run(View.java:17721)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at android.os.Handler.handleCallback(Handler.java:730)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at android.os.Handler.dispatchMessage(Handler.java:92)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at android.os.Looper.loop(Looper.java:137)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at android.app.ActivityThread.main(ActivityThread.java:5103)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at java.lang.reflect.Method.invokeNative(Native Method)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at java.lang.reflect.Method.invoke(Method.java:525)
03-25 15:22:23.465    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
03-25 15:22:23.469    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
03-25 15:22:23.469    2073-2073/com.sblive.aufschoolbliz W/System.err﹕ at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • ECB 模式通常只有在消息小于或等于 16 字节时才能安全使用。一旦消息变得大于 16 字节,该模式就会泄漏信息。改用 CBC 模式。
  • 改了但是没用..
  • 似乎 encryptedUsernameencyptedPassword 是字符串,您正试图将它们视为字节数组的持有者。您应该将加密数据存储为byte[],并将其作为byte[] 传递。或者至少转换为 Base64 并适当地返回。
  • "...更改了它但它不起作用" - 确保每次加密都使用SecureRandom 生成的随机 IV。否则,所有消息都使用 NULL IV 并再次泄漏信息。请参阅 Java 文档中的 IvParameterSpec
  • 如果你的Java版本支持,你也应该考虑使用GCM模式。它不仅加密,还提供真实性保证。使用 GCM 模式,您几乎可以免费获得位损坏和篡改检测。我说“几乎免费”是因为 auth 标签会导致一些额外的纯文本扩展。

标签: java android encryption cryptography


【解决方案1】:

加密用户名:[B@52aff408

加密密码:[B@52aff6d8

这些太小了。假设纯文本消息少于 16 个字节,那么由于 PKCS 填充,这些应该正好是 16 个字节。

您在某个地方遇到了编码问题。可能是一个嵌入的空值,它在解释为字符串时会切断密文的结尾......

事实上,它们看起来就像被打印的指针......

【讨论】:

  • 哦,是的,当我将 String.valueOf 存储到共享首选项时,我正在使用它。但是,我现在得到了用于加密的未知字符,如下所示:“�)��J;]�w.6�t"
  • "现在正在获取未知字符进行加密..." - 您可能需要不同的策略来处理原始字节。特别是如果您试图将它们视为可打印的字符串。您可以根据需要对它们进行 Hex/Base32/Base64 编码(和解码)。
猜你喜欢
  • 2017-12-20
  • 1970-01-01
  • 2014-05-31
  • 2015-06-30
  • 2016-03-22
  • 1970-01-01
  • 2014-02-13
  • 1970-01-01
  • 2020-04-30
相关资源
最近更新 更多