我正在使用AESCrypt (gradle :compile 'com.scottyab:aescrypt:0.0.1')加密和解密数据。

  TextView  tv=(TextView)findViewById(R.id.demotext);
    String encrypted="",decrypted="";
    try {
        encrypted = AESCrypt.encrypt("password","This is the best thing to go by");

        decrypted = AESCrypt.decrypt("password",encrypted);
    } catch (GeneralSecurityException e) {
        e.printStackTrace();
    }
    System.out.println("EncryptedData:"+encrypted);
    System.out.println("DecryptedData:"+decrypted);
    tv.setText("Encrypted:"+encrypted +"\n"+"Decrypted:"+decrypted);

在这种情况下,代码工作得很好,我得到的输入与解密文本相同。

但是,当我尝试使用来自站点http://aesencryption.net/的相同方法( AES AES )使用已经加密的字符串时,如屏幕截图所示:

java - javax.crypto.BadPaddingException AES-LMLPHP

然后复制粘贴该加密文本,例如:
decrypted = AESCrypt.decrypt("password","sttA+FbNm3RkTovjHI8CcAdStXiMl45s29Jqle+y+pA=");

然后运行代码,然后出现错误消息:
javax.crypto.BadPaddingException: error:1e06b065:Cipher functions:EVP_DecryptFinal_ex:BAD_DECRYPT

java - javax.crypto.BadPaddingException AES-LMLPHP

但是,当我将解密的文本用于同一个站点时,效果很好,如下面的屏幕快照所示。

java - javax.crypto.BadPaddingException AES-LMLPHP
private static byte[] decrypt(byte[] raw, byte[] encrypted) throws Exception {
        SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
        Cipher cipher = Cipher.getInstance("AES");
        cipher.init(Cipher.DECRYPT_MODE, skeySpec);
        byte[] decrypted = cipher.doFinal(encrypted);
        return decrypted;
    }

最佳答案

可能是由于将密码短语“密码”转换为SecretKeySpec的算法

这是AESCrypt中的算法

private static SecretKeySpec GenerateKey (final String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {    
     final MessageDigest digest = MessageDigest.getInstance (HASH_ALGORITHM);
     byte [] bytes = password.getBytes ("UTF-8");
     digest.update (bytes, 0, bytes.length);
     byte [] key = digest.digest ();

     log ("SHA-256 key" key);

     SecretKeySpec secretKeySpec = new SecretKeySpec (key, "AES");
     secretKeySpec return;
  }

这是(Java)示例aesencryption.net
sha = MessageDigest.getInstance ("SHA-1");
key = sha.digest (key);
key = Arrays.copyOf (key, 16); // Use only first 128 bit
SecretKey = new SecretKeySpec (key, "AES");

第一个应用SHA256哈希,第二个SHA-1完成最多16个字节后,因此密钥是不同的。

我认为您正在以正确的方式加密和解密AES。您无需更改任何内容。

但是,如果要与aesencryption.net兼容,则需要实现相同的密钥生成算法。代码不太好。我尝试总结一下
//Code from aesencryption.net
// Generate key
MessageDigest sha = null;
key = myKey.getBytes ("UTF-8");
sha = MessageDigest.getInstance ("SHA-1");
key = sha.digest (key);
key = Arrays.copyOf (key, 16); // Use only first 128 bit
SecretKey = new SecretKeySpec (key, "AES");

public static String encrypt (String strToEncrypt) {
     Cipher cipher = Cipher.getInstance ("AES / ECB / PKCS5Padding");
     cipher.init (Cipher.ENCRYPT_MODE, SecretKey);
     Base64.encodeBase64String return (cipher.doFinal (strToEncrypt.getBytes ("UTF-8"))));
}

public static String decrypt (String strToDecrypt) {
     Cipher cipher = Cipher.getInstance ("AES / ECB / PKCS5PADDING");
     cipher.init (Cipher.DECRYPT_MODE, SecretKey);
     return new String (cipher.doFinal (Base64.decodeBase64 (strToDecrypt))));
}

我还可以提供从Android应用程序中提取的自己的代码,这些代码需要存储私人用户数据。数据使用受用户密码保护的AES密钥加密
public static String SIMMETRICAL_ALGORITHM = "AES";

//Generate cipher key with user provided password
private static String getPassphraseSize16(String key) {
    if (TextUtils.isEmpty(key)) {
        return null;
    }
    char controlChar = '\u0014';
    String key16 = key + controlChar;
    if (key16.length() < 16) {
        while (key16.length() < 16) {
            key16 += key + controlChar;
        }
    }
    if (key16.length() > 16) {
        key16 = key16.substring(key16.length() - 16, key16.length());
    }
    return key16;
}

//AES cipher with passphrase
public static byte[] encrypt(byte[] message, String passphrase)
        throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    String passphrase16 = getPassphraseSize16(passphrase);

    SecretKeySpec secretKey = new SecretKeySpec(passphrase16.getBytes(), SIMMETRICAL_ALGORITHM);
    Cipher cipher = Cipher.getInstance(SIMMETRICAL_ALGORITHM);
    cipher.init(Cipher.ENCRYPT_MODE, secretKey);
    byte[] encoded = cipher.doFinal(message);

    return encoded;
}

//AES decipher with passphrase
public static byte[] decrypt(byte[] encodedMessage, String key) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
    String passphrase16 = getPassphraseSize16(key);

    SecretKeySpec secretKey = new SecretKeySpec(passphrase16.getBytes(), SIMMETRICAL_ALGORITHM);
    Cipher cipher = Cipher.getInstance(SIMMETRICAL_ALGORITHM);
    cipher.init(Cipher.DECRYPT_MODE, secretKey);
    byte decoded[] = cipher.doFinal(encodedMessage);

    return decoded;
}

09-25 21:04