Android学习笔记(一)
#### 要点
1、在存储密钥时,要在Android环境下调试,不然下面的代码会报Not found 'AndroidKeyStore'
,根本原因是在PC java环境下与Android下load的方式不同。
1 2
| KeyStore keyStore = KeyStore.getInstance(alias); keyStore.load(null);
|
2、如果要设置自己的初始向量IV,关闭自动生成随机初始向量IV,需要设置以下代码:
1
| setRandomizedEncryptionRequired(false)
|
自定义初始向量IV长度为12byte,即iv = byte[12]
3、在byte[] 与String不能够等价的转换,即装换是不可逆的,将一个byte数组转换为String后再转换为byte[],两者等价了。因此在加密的时候使用了Base64来做转码功能。
4、IV只支持GCMParameterSpec iv = new GCMParameterSpec(128, sIv.getBytes("UTF-8"));
生成的初始向量,使用别的会报错。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
| package com.zyl315.acfun.utils;
import android.os.Build; import android.security.keystore.KeyGenParameterSpec; import android.security.keystore.KeyProperties; import android.util.Base64;
import java.security.KeyStore;
import javax.crypto.Cipher; import javax.crypto.KeyGenerator; import javax.crypto.SecretKey; import javax.crypto.spec.GCMParameterSpec;
import androidx.annotation.RequiresApi;
public class EncryptTool { private static final String alias = "AndroidKeyStore"; private static final String sIv = "qwertyuiopas"; @RequiresApi(api = Build.VERSION_CODES.M) public static String encrypt(String password) { try { final KeyGenerator keyGenerator = KeyGenerator.getInstance(KeyProperties.KEY_ALGORITHM_AES); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
} else { final KeyGenParameterSpec keyGenParameterSpec = new KeyGenParameterSpec.Builder(alias, KeyProperties.PURPOSE_ENCRYPT | KeyProperties.PURPOSE_DECRYPT) .setBlockModes(KeyProperties.BLOCK_MODE_GCM) .setEncryptionPaddings(KeyProperties.ENCRYPTION_PADDING_NONE) .setRandomizedEncryptionRequired(false) .build(); keyGenerator.init(keyGenParameterSpec); } final SecretKey secretKey = keyGenerator.generateKey(); final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); GCMParameterSpec iv = new GCMParameterSpec(128, sIv.getBytes("UTF-8")); cipher.init(Cipher.ENCRYPT_MODE, secretKey, iv); byte[] encryption = cipher.doFinal(password.getBytes("UTF-8")); return new String(Base64.encode(encryption, Base64.DEFAULT),"UTF-8"); } catch (Exception e) { e.printStackTrace(); } return null; }
@RequiresApi(api = Build.VERSION_CODES.M) public static String decrypt(String encryption) { try { byte[] data = Base64.decode(encryption, Base64.DEFAULT); KeyStore keyStore = KeyStore.getInstance(alias); keyStore.load(null); final KeyStore.SecretKeyEntry secretKeyEntry = (KeyStore.SecretKeyEntry) keyStore.getEntry(alias, null); final SecretKey secretKey = secretKeyEntry.getSecretKey(); final Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding"); final GCMParameterSpec spec = new GCMParameterSpec(128, sIv.getBytes("UTF-8")); cipher.init(Cipher.DECRYPT_MODE, secretKey, spec); final byte[] decodedData = cipher.doFinal(data); return new String(decodedData, "UTF-8"); } catch (Exception e) { e.printStackTrace(); } return null; } }
|
附一张AC新的登录页面背景图,