如何使用AES Android进行加密

时间:2018-09-18 12:02:04

标签: android encryption aes

我想用密钥和Iv加密字符串。但是我没有得到正确的加密。谁能告诉我该怎么做。 我的字符串是abc,但是在解密字符串时,它包含特殊字符。 我点击了此链接: https://www.cuelogic.com/blog/using-cipher-to-implement-cryptography-in-android/

package com.reshhhjuuitos.mhhhkoiyrestos.footer;
import java.security.NoSuchAlgorithmException;
import javax.crypto.Cipher;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
public class MCrypt {
    private String iv = "1234567890123456";            // Dummy iv (CHANGE IT!)
    private IvParameterSpec ivspec;
    private SecretKeySpec keyspec;
    private Cipher cipher;
    private String SecretKey = "1&BZ6pqSu1w2%7!8w0oQHJ7FF79%+MO2";
    public MCrypt() {
        ivspec = new IvParameterSpec(iv.getBytes());
        keyspec = new SecretKeySpec(SecretKey.getBytes(), "AES");

        try {
            //cipher = Cipher.getInstance("AES/CBC/NoPadding");
            cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        catch (NoSuchPaddingException e) {
            e.printStackTrace();
        }
    }
    public byte[] encrypt(String text) throws Exception {
        if (text == null || text.length() == 0)
            throw new Exception("Empty string");

        byte[] encrypted = null;
        try {
// Cipher.ENCRYPT_MODE = Constant for encryption operation mode.
            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);

            encrypted = cipher.doFinal(padString(text).getBytes("UTF-8"));
        } catch (Exception e) {
            throw new Exception("[encrypt] " + e.getMessage());
        }
        return encrypted;
    }
    private static String padString(String source) {
        char paddingChar = 0;
        int size = 16;
        int x = source.length() % size;
        int padLength = size - x;
        for (int i = 0; i < padLength; i++) {
            source += paddingChar;
        }
        return source;
    }
    public static byte[] hexToBytes(String str) {
        if (str == null) {
            return null;
        } else if (str.length() < 2) {
            return null;
        } else {

            int len = str.length() / 2;
            byte[] buffer = new byte[len];
            for (int i = 0; i < len; i++) {
                buffer[i] = (byte) Integer.parseInt(
                        str.substring(i * 2, i * 2 + 2), 16);

            }
            return buffer;
        }
    }
    public static String byteArrayToHexString(byte[] array) {
        StringBuffer hexString = new StringBuffer();
        for (byte b : array) {
            int intVal = b & 0xff;
            if (intVal < 0x10)
                hexString.append("0");
            hexString.append(Integer.toHexString(intVal));
        }
        return hexString.toString();
    }
    public byte[] decrypt(String text) throws Exception {
        if (text == null || text.length() == 0)
            throw new Exception("Empty string");

        byte[] decrypted = null;
        try {
// Cipher.DECRYPT_MODE = Constant for decryption operation mode.
            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);

            decrypted = cipher.doFinal(hexToBytes(text));
        } catch (Exception e) {
            throw new Exception("[decrypt] " + e.getMessage());
        }
        return decrypted;
    }
}

MainACTVITIY.JAVA

MCrypt mycrypt = new MCrypt();
        String dummyStr = "abc";
        try {
            String encryptedStr = mycrypt.byteArrayToHexString(mycrypt.encrypt(dummyStr));
            String decryptedStr = new String(mycrypt.decrypt(encryptedStr));
            Log.v("Tag_en",""+encryptedStr);
            Log.v("Tag_de",""+decryptedStr);
        } catch (Exception e) {
            e.printStackTrace();
        }

output:Tag_en:5b49ac218b93ee5315c25a0e40b3e9de42e6ecadf0827062b22d4421da99dc5a  Tag_de:abc��������������������������

3 个答案:

答案 0 :(得分:2)

好的,我想可能是您的十六进制编码/解码,但是它们可以工作。因此,我编写了一些快速加密并针对您的班级进行了测试。

问题是您的填充。我不明白为什么要将字符串填充到长度16,但是添加到字符串的空字符是无法打印的。因此,要么不填充字符串,要么在解密过程中去除填充空值,以重建您加密的确切字符串。

为了清晰,可维护性和可重用性,您实际上应该在每个方法中仅执行一个清晰的逻辑操作,即,应在将字符串传递给加密方法之前执行填充操作,这样加密方法才进行加密。 / p>

答案 1 :(得分:0)

您可以使用以下功能:

private static byte[] encrypt(byte[] raw, byte[] clear) throws Exception {
    SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
    Cipher cipher = Cipher.getInstance("AES");
    cipher.init(Cipher.ENCRYPT_MODE, skeySpec);
    byte[] encrypted = cipher.doFinal(clear);
    return encrypted;
}

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;
}

并像这样调用它们:

ByteArrayOutputStream baos = new ByteArrayOutputStream();  
bm.compress(Bitmap.CompressFormat.PNG, 100, baos); // bm is the bitmap object   
byte[] b = baos.toByteArray();  

byte[] keyStart = "this is a key".getBytes();
KeyGenerator kgen = KeyGenerator.getInstance("AES");
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed(keyStart);
kgen.init(128, sr); // 192 and 256 bits may not be available
SecretKey skey = kgen.generateKey();
byte[] key = skey.getEncoded();    

// encrypt
byte[] encryptedData = encrypt(key,b);
// decrypt
byte[] decryptedData = decrypt(key,encryptedData);

这应该可行,我现在在项目中使用类似的代码。

答案 2 :(得分:0)

尝试此代码,对我有用

attributes