Android数据安全之AES加密
来源:互联网 发布:吉利电动车知豆d2价钱 编辑:程序博客网 时间:2024/06/08 07:56
对称加密算法,加密和解密使用相同密钥的算法。优点:加密速度比较快.可以加密比较大的文件;缺点:密码可以自己指定 ,密码容易泄露
背景
AES(Advanced Encryption Standard)高级加密标准,安全性要高于DES,其实AES的出现本身就是为了取代DES的,AES具有比DES更好的安全性、效率、灵活性,所以对称加密优先采用AES。在密码学中又称Rijndael加密法,是美国联邦政府采用的一种区块加密标准。这个标准用来替代原先的DES。
应用场景
项目中除了登陆,支付等接口采用RAS非对称加密,之外的可以采用AES对称加密
对称加密过程
对称密码的加密方案有5个组成部分(如图所示)
1)明文:原始信息。
2)加密算法:以密钥为参数,对明文进行多种置换和转换的规则和步骤,变换结果为密文。
3)密钥:加密与解密算法的参数,直接影响对明文进行变换的结果。
4)密文:对明文进行变换的结果。
5)解密算法:加密算法的逆变换,以密文为输入、密钥为参数,变换结果为明文。
对称密码中的数学运算
对称密码当中有几种常用到的数学运算。这些运算的共同目的就是把被加密的明文数码尽可能深地打乱,从而加大破译的难度。
- 移位和循环移位
移位就是将一段数码按照规定的位数整体性地左移或右移。循环右移就是当右移时,把数码的最后的位移到数码的最前头,循环左移正相反。例如,对十进制数码12345678循环右移1位(十进制位)的结果为81234567,而循环左移1位的结果则为23456781。 - 置换
就是将数码中的某一位的值根据置换表的规定,用另一位代替。它不像移位操作那样整齐有序,看上去杂乱无章。这正是加密所需,被经常应用。 - 扩展
就是将一段数码扩展成比原来位数更长的数码。扩展方法有多种,例如,可以用置换的方法,以扩展置换表来规定扩展后的数码每一位的替代值。 - 压缩
就是将一段数码压缩成比原来位数更短的数码。压缩方法有多种,例如,也可以用置换的方法,以表来规定压缩后的数码每一位的替代值。 - 异或
这是一种二进制布尔代数运算。异或的数学符号为⊕ ,它的运算法则如下:
1⊕1 = 0
0⊕0 = 0
1⊕0 = 1
0⊕1 = 1
也可以简单地理解为,参与异或运算的两数位如相等,则结果为0,不等则为1。 - 迭代
迭代就是多次重复相同的运算,这在密码算法中经常使用,以使得形成的密文更加难以破解。
AES代码实现
1)常量简介
private final static String HEX = "0123456789ABCDEF";private static final String CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding";//AES是加密方式 CBC是工作模式 PKCS5Padding是填充模式private static final String AES = "AES";//AES 加密private static final String SHA1PRNG = "SHA1PRNG";// SHA1PRNG 强随机种子算法, 要区别4.2以上版本的调用方法
2)动态生成秘钥
/** * 动态生成密钥 * * @return 生成随机数,可以当做动态的密钥 加密和解密的密钥必须一致,不然将不能解密 */public static String generateKey() { try { SecureRandom secureRandom = SecureRandom.getInstance(SHA1PRNG, "Crypto"); byte[] bytesKey = new byte[20];// 长度不能够小于8位字节 因为DES固定格式为64bits,即8bytes。 secureRandom.nextBytes(bytesKey); String strKey = ByteToHex(bytesKey); return strKey; } catch (Exception e) { e.printStackTrace(); } return null;}
3)处理秘钥Key(转换密钥)
/** * 对密钥进行处理 */private static byte[] getRawKey(String key) throws Exception { KeyGenerator kgen = KeyGenerator.getInstance(AES); //for android // 在4.2以上版本中,SecureRandom获取方式发生了改变 SecureRandom sr = SecureRandom.getInstance(SHA1PRNG, "Crypto"); // for Java // secureRandom = SecureRandom.getInstance(SHA1PRNG); sr.setSeed(key.getBytes()); kgen.init(128, sr); //256 bits or 128 bits,192bits //AES中128位密钥版本有10个加密循环,192比特密钥版本有12个加密循环,256比特密钥版本则有14个加密循环。 SecretKey skey = kgen.generateKey(); byte[] raw = skey.getEncoded(); return raw;}
4)加密实现
/** * AES加密 */public static String encrypt(String key, String data) { if (TextUtils.isEmpty(data)) { return data; } try { byte[] result = encrypt(key, data.getBytes()); //return new String(result);//直接将经过加密后的字节数组利用String的API转成字符串只能得到乱码 //return ByteToHex(result);//采用的byte[] 到 String 转换的方法都是将 byte[] 二进制利用16进制的char[]来表示 return Base64.encodeToString(result, Base64.DEFAULT);//采用Android中Base64将AES加密后数据转成字符串同时实现(再次加密转化为暗文) //return Base64Encoder.encode(result);//采用Base64Encoder类来实现,效果和原生的Base64效果一样 } catch (Exception e) { e.printStackTrace(); } return null;}/** * AES加密 */private static byte[] encrypt(String key, byte[] bytes) throws Exception { byte[] raw = getRawKey(key); SecretKeySpec skeySpec = new SecretKeySpec(raw, AES); Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING); cipher.init(Cipher.ENCRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] encrypted = cipher.doFinal(bytes); return encrypted;}
5)解密实现
/** * AES 解密 */public static String decrypt(String key, String data) { if (TextUtils.isEmpty(data)) { return data; } try { //byte[] bytes = HexToByte(data); //byte[] bytes = Base64Decoder.decodeToBytes(data); byte[] bytes = Base64.decode(data, Base64.DEFAULT); byte[] result = decrypt(key, bytes); return new String(result); } catch (Exception e) { e.printStackTrace(); } return null;}/** * AES 解密 */private static byte[] decrypt(String key, byte[] data) throws Exception { byte[] raw = getRawKey(key); SecretKeySpec skeySpec = new SecretKeySpec(raw, AES); Cipher cipher = Cipher.getInstance(CBC_PKCS5_PADDING); cipher.init(Cipher.DECRYPT_MODE, skeySpec, new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] decrypted = cipher.doFinal(data); return decrypted;}
6)进制转换
/** * 二进制转(16进制)字符串 */private static String ByteToHex(byte[] bytesKey) { if (bytesKey == null) return ""; StringBuilder sb = new StringBuilder(); for (byte b : bytesKey) { sb.append(HEX.charAt((b >> 4) & 0x0f)).append(HEX.charAt(b & 0x0f)); } return sb.toString();}/** * (16进制)字符转二进制 */private static byte[] HexToByte(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;}
7)测试
private String data = "这是一个测试编码和加解密的字符串数据";private String AES_Key = "aeskey";private boolean isAesEncrypt = true;/** * AES 加解密 */private void aesEncrypt() { tvContent.setText(""); if (isAesEncrypt) { encryptAES = AESUtils.encrypt(AES_Key, data); Log.d("TAG:" + TAG, "----AES加密后: " + encryptAES); tvContent.setText("AES加密后: " + encryptAES); } else { String decryptAES = AESUtils.decrypt(AES_Key, encryptAES); Log.d("TAG:" + TAG, "----AES解密后: " + decryptAES); tvContent.setText("AES解密后: " + decryptAES); } isAesEncrypt = !isAesEncrypt;}
追及
完整代码参考github:Android-Encrypt-master
1 0
- Android数据安全之AES加密
- C#数据安全加密之AES
- Android数据加密之Aes加密
- Android 数据加密之RSA + AES
- android 数据加密AES
- Android之AES加密
- android之AES加密
- android 安全之——文件加密AES加密算法
- android 安全之——文件加密AES加密算法、
- Android数据加密之RSA+AES混合加密
- android 使用Aes加密数据
- java、android、ios、js数据传递加密算法之AES加密
- android数据加密(二)AES加密
- android之AES加密解密
- Android之"AES"加密解密
- Android数据安全之MD5加密
- Android数据安全之DES加密
- Android数据安全之异或加密
- Codeforces Round #406 (Div. 2) C 博弈
- 复习之路
- 超简单BeautifulSoup版Csdn博客(摘要视图)爬虫
- 1102. Invert a Binary Tree 解析
- 分类:情感分析
- Android数据安全之AES加密
- Android线程和线程池
- 推荐系统学习(一)——推荐引擎初探
- 数据结构之图的邻接表的基本操作
- 由一道js题探讨构造函数、prototype和__proto__之间的关系
- intellij idea 2017 部署 JavaEE web application 步骤
- Android 动画学习(一)之View Animation
- 算法实验之贪心策略求解背包问题
- C语言基础注意点