简单的AES加密和解密不返回原始文本

时间:2014-05-27 09:05:00

标签: android security encryption aes

我正在使用以下简单的加密和解密函数,只是为了看它在使用更复杂的安全功能(如填充和散列)之前的工作原理。由于某种原因,返回的明文与原始邮件不相似。这是代码:

public static byte[] encrypt(SecretKey secret, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException
{
    /* Encrypt the message. */
    cipher = Cipher.getInstance("AES/CTR/NoPadding");
    cipher.init(Cipher.ENCRYPT_MODE, secret);
    byte[] ciphertext = cipher.doFinal(buffer);

    return ciphertext;
}

public static byte[] decrypt(SecretKey secret, byte[] buffer) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidParameterSpecException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException
{
    /* Decrypt the message. - use cipher instance created at encrypt */
    cipher.init(Cipher.DECRYPT_MODE, secret);
    byte[] clear = cipher.doFinal(buffer);

    return clear;
}

和调用代码:

    SecretKey secret1 = null;
    byte[] ciphertext = null;
    byte[] message = "Hello, World!".getBytes();
    byte[] clear = null;

    try {
// aSecret is a shared secret generated with ECDH
        secret1 = Crypto.createAESKey(aSecret);
        ciphertext = Crypto.encrypt(secret1, message);
        clear = Crypto.decrypt(secret1, ciphertext);

        String s = new  String(clear);//clear.toString();

        keyAText.setText(new String(message));
        keyBText.setText(s);

        return;
    } catch (InvalidKeySpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchAlgorithmException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (NoSuchPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidParameterSpecException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IllegalBlockSizeException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (BadPaddingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (UnsupportedEncodingException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

1 个答案:

答案 0 :(得分:2)

这几乎可以肯定是因为您在初始化期间未使用IvParameterSpec提供IV。在Java SE上,由于CTR 需要设置此参数,因此您的代码甚至无法运行。然而,其他提供商可能以不同的方式实现他们可能会提供一个随机的IV。

当然,如果您在加密和解密期间使用不同的随机IV,您的解密结果可能与您的明文不匹配。

尝试以下修正方法:

public static byte[] encrypt(SecretKey secret, byte[] buffer) throws GeneralSecurityException
{
    /* Encrypt the message. */
    Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");

    SecureRandom rng = new SecureRandom();
    byte[] ivData = new byte[cipher.getBlockSize()];
    rng.nextBytes(ivData);

    cipher.init(Cipher.ENCRYPT_MODE, secret, new IvParameterSpec(ivData));
    byte[] ciphertext = cipher.doFinal(buffer);

    return Arrays.concatenate(ivData, ciphertext);
}

public static byte[] decrypt(SecretKey secret, byte[] buffer) throws GeneralSecurityException
{
    /* Decrypt the message. - use cipher instance created at encrypt */
    Cipher cipher = Cipher.getInstance("AES/CTR/NoPadding");

    int n = cipher.getBlockSize();
    byte[] ivData = Arrays.copyOf(buffer, n);

    cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(ivData));
    byte[] clear = cipher.doFinal(buffer, n, buffer.length - n);

    return clear;
}