android - AES/CBC/PKCS5Padding加密解密算法和SHA-1哈希算法是否适用于所有类型的Android设备

标签 android encryption cryptography

我曾尝试在 Nexus 5 中运行以下 AES/CBC/PKCS5Padding 加密和解密代码,使用 SHA-1 作为 key 生成。它运行良好到目前为止。

然而,我唯一担心的是,AES/CBC/PKCS5Padding 加密解密算法和 SHA-1 哈希算法是否适用于所有类型的 Android 设备?

以下代码是否有可能无法在某些 Android 设备上运行?如果有,是否有后备方案?

AES/CBC/PKCS5Padding

// http://stackoverflow.com/questions/3451670/java-aes-and-using-my-own-key
public static byte[] generateKey(String key) throws GeneralSecurityException, UnsupportedEncodingException {
    byte[] binary = key.getBytes("UTF-8");
    MessageDigest sha = MessageDigest.getInstance("SHA-1");
    binary = sha.digest(binary);
    // Use only first 128 bit.
    binary = Arrays.copyOf(binary, 16);
    return binary;
}

// http://stackoverflow.com/questions/17322002/what-causes-the-error-java-security-invalidkeyexception-parameters-missing
public static String encrypt(byte[] key, String value) throws GeneralSecurityException {
    // Argument validation.
    if (key.length != 16) {
        throw new IllegalArgumentException("Invalid key size.");
    }

    // Setup AES tool.
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));

    // Do the job with AES tool.
    byte[] original = value.getBytes(Charset.forName("UTF-8"));
    byte[] binary = cipher.doFinal(original);
    return Base64.encodeToString(binary, Base64.DEFAULT);
}

// // http://stackoverflow.com/questions/17322002/what-causes-the-error-java-security-invalidkeyexception-parameters-missing
public static String decrypt(byte[] key, String encrypted) throws GeneralSecurityException {
    // Argument validation.
    if (key.length != 16) {
        throw new IllegalArgumentException("Invalid key size.");
    }

    // Setup AES tool.
    SecretKeySpec skeySpec = new SecretKeySpec(key, "AES");
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[16]));

    // Do the job with AES tool.
    byte[] binary = Base64.decode(encrypted, Base64.DEFAULT);
    byte[] original = cipher.doFinal(binary);
    return new String(original, Charset.forName("UTF-8"));
}

用法

byte[] key = generateKey("my secret key");
String ciphertext = encrypt(key, "my plain content");
String plainContent = decrypt(key, ciphertext);

最佳答案

不,它不太可能会失败。 Android API 派生自 Java API。自 1.4 版以来,Java API 已包含 "AES/CBC/PKCS5Padding"

至于“SHA-1”,那是一种更古老的算法,从一开始就得到支持。

注意不要使用 "PKCS7Padding" 代替。 Java 使用 "PKCS5Padding" 作为替代,"PKCS7Padding" 支持可能是粗略的,即使它意味着相同的事情。


请注意,您应该使用基于密码的加密 (PBE) 而不是 AES/CBC 和 SHA-1。特别是使用 SHA-1 作为 key 派生方法特别危险,因为您没有像 PBKDF2 这样的基于密码的 key 派生函数那样使用盐或工作因子。基本上只有当您知道您的密码包含足够的熵时才这样做。

不过,对同一个 key 使用全零 IV 更糟糕(正如评论中已经指出的那样)。它允许攻击者找到重复的(起始 block )明文输入。始终建议使用经过身份验证的加密(例如使用 HMAC-SHA-1),传输模式加密或多或少需要这种加密方式(与无法进行明文/填充 oracle 攻击的就地加密相反)。

关于android - AES/CBC/PKCS5Padding加密解密算法和SHA-1哈希算法是否适用于所有类型的Android设备,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29574587/

相关文章:

android - 进度条问题

android - 我的应用程序上的youtube输出,而未使用标准浏览器和webview

android - 从 sqlite 数据库中检索特定的表项

android - onCheckedChanged 自动调用

c# - 如何使用 rs256 算法使用我自己的 rsa 私钥对字节进行签名?

java - RSA加密-字节数组和字符串之间的转换

c# - 给要加密的数据加盐?

java - 如何为中间相遇攻击收集数据?

android - 在 iOS 设备上安全存储个人用户数据

node.js - 使用 ECDH 和 nodejs 加密解密 secret