繁体   English   中英

Android,SharedPreferences可记住使用AES-128加密的登录详细信息,但不会解密

[英]Android, SharedPreferences to remember login details with AES-128 encryption but won't decrypt

我正在尝试做的是:

在Android中,我尝试使用SharedPreferences将用户名存储在应用程序内存中。 因此,用户无需每次都输入用户名,但该应用程序不会解密用户名。 没有加密,它将存储并返回用户名,但是使用AES-128加密,不会解密/返回用户名。

发生了什么:

该程序将新加密的用户名存储在内存中,但是当应用程序尝试对它们进行解密时,什么也没有发生(用户名文本框返回为空)。

该应用程序打算执行的操作:(但未执行)

用户应输入其用户名和密码,如果他们单击“记住”复选框,则在按下登录按钮后,应用程序将存储并加密其用户名。

在将来运行该应用程序时,如果先前已选中该复选框,则其用户名将已经出现在用户名文本框中。 当按钮功能完成时,然后通过“ doSomethinghElse”子例程重新启动该应用程序,以便向我确认该应用程序已工作并且返回了未加密的用户名。 但这不是现在发生

实际问题:

它不是解密和返回用户名。 加密,删除尝试和捕获后,该应用将返回前一个用户的登录详细信息。 但是,加上加密功能,该应用程序不会返回用户名。

为了帮助人们解决此问题,以下内容主要基于以下两个链接:

添加“记住我”复选框

http://www.androidsnippets.com/encryptdecrypt-strings

码:

Crypto.java

public class Crypto {
    public static String encrypt(String seed, String cleartext)
            throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] result = encrypt(rawKey, cleartext.getBytes());
        return toHex(result);
    }

    public static String decrypt(String seed, String encrypted)
            throws Exception {
        byte[] rawKey = getRawKey(seed.getBytes());
        byte[] enc = toByte(encrypted);
        byte[] result = decrypt(rawKey, enc);
        return new String(result);
    }

    private static byte[] getRawKey(byte[] seed) throws Exception {
        KeyGenerator kgen = KeyGenerator.getInstance("AES");
        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
        sr.setSeed(seed);
        kgen.init(128, sr); // 192 and 256 bits may not be available
        SecretKey skey = kgen.generateKey();
        byte[] raw = skey.getEncoded();
        return raw;
    }

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

    public static String toHex(String txt) {
        return toHex(txt.getBytes());
    }

    public static String fromHex(String hex) {
        return new String(toByte(hex));
    }

    public static byte[] toByte(String hexString) {
        int len = hexString.length() / 2;
        byte[] result = new byte[len];
        for (int i = 0; i < len; i++)
            result[i] = Integer.valueOf(hexString.substring(2 * i, 2 * i + 2),
                    16).byteValue();
        return result;
    }

    public static String toHex(byte[] buf) {
        if (buf == null)
            return "";
        StringBuffer result = new StringBuffer(2 * buf.length);
        for (int i = 0; i < buf.length; i++) {
            appendHex(result, buf[i]);
        }
        return result.toString();
    }

    private final static String HEX = "0123456789ABCDEF";

    private static void appendHex(StringBuffer sb, byte b) {
        sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f));
    }
}

编码:

     public String encryptString(String dataToEncrypt) {

        try {
            SharedPreferences prefs = context.getSharedPreferences("appname", 0);
            if (prefs.getString("SECRET_KEY","") == "") {
                secretKeySpec = GenerateSecretKeySpecs();
                String stringSecretKey = Base64.encodeToString(
                        secretKeySpec.getEncoded(), Base64.DEFAULT);

                SharedPreferences.Editor editor = prefs.edit();
                editor.putString("SECRET_KEY", stringSecretKey);
                editor.commit();

            }
            if (prefs.getString("SECRET_KEY","") != "") {
                byte[] encodedBytes = null;

                Cipher c = Cipher.getInstance("AES");
                String key =prefs.getString("SECRET_KEY","");

                byte[] encodedKey = Base64.decode(key, Base64.DEFAULT);
                SecretKey originalKey = new SecretKeySpec(encodedKey, 0,
                        encodedKey.length, "AES");
                c.init(Cipher.ENCRYPT_MODE, originalKey);
                encodedBytes = c.doFinal(dataToEncrypt.getBytes());

                return Base64.encodeToString(encodedBytes, Base64.DEFAULT);
            } else {
                return null;
            }
        } catch (Exception e) {
//          Log.e(TAG, "AES encryption error");
            return null;
        }
    }

解码:

public String decryptString(String dataToDecrypt) {
        SharedPreferences prefs= context.getSharedPreferences("appname", 0);
        if (prefs.getString("SECRET_KEY","") != "") {
            byte[] decodedBytes = null;
            try {
                Cipher c = Cipher.getInstance("AES");

                String key = prefs.getString("SECRET_KEY","")
                byte[] encodedKey = Base64.decode(key, Base64.DEFAULT);
                SecretKey originalKey = new SecretKeySpec(encodedKey, 0,
                        encodedKey.length, "AES");
                c.init(Cipher.DECRYPT_MODE, originalKey);

                byte[] dataInBytes = Base64.decode(dataToDecrypt,
                        Base64.DEFAULT);

                decodedBytes = c.doFinal(dataInBytes);
                return new String(decodedBytes);
            } catch (Exception e) {
//              Log.e(TAG, "AES decryption error");
                e.printStackTrace();
                return null;
            }

        } else
            return null;

    }

范例:

String encrypted_password = encryptString(MPwd);
String decrypted_password = decryptString(encrypted_password);

我已经使用了这段代码,它工作正常。

希望对您有帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM