目录

一、问题

二、解决源码


一、问题

在Java 后端发来的AES加密数据时,发现Android APP不能解密 而且Android 端 加密同样的数据返回的结果居然不一致,所以我在网上查询后,发现在SecureRandom在产生安全随机数时 Windows系统和Linux系统的机制不一样,所以在同样的java AES加密源码加密同意的数据产生不一样的加密结果。

下面我给出网络的常用的AES加密的源码。

网络常用的AES加解密源码:

/*** AES加密字符串** @param content*            需要被加密的字符串* @param password*            加密需要的密码* @return 密文*/public static byte[] encrypt(String content, String password) {try {KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者kgen.init(128, new SecureRandom(password.getBytes()));// 利用用户密码作为随机数初始化出// 128位的key生产者//加密没关系,SecureRandom是生成安全随机数序列,password.getBytes()是种子,只要种子相同,序列就一样,所以解密只要有password就行SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回// null。SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥Cipher cipher = Cipher.getInstance("AES");// 创建密码器byte[] byteContent = content.getBytes("utf-8");cipher.init(Cipher.ENCRYPT_MODE, key);// 初始化为加密模式的密码器byte[] result = cipher.doFinal(byteContent);// 加密return result;} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (UnsupportedEncodingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}/*** 解密AES加密过的字符串** @param content*            AES加密过过的内容* @param password*            加密时的密码* @return 明文*/public static byte[] decrypt(byte[] content, String password) {try {KeyGenerator kgen = KeyGenerator.getInstance("AES");// 创建AES的Key生产者kgen.init(128, new SecureRandom(password.getBytes()));SecretKey secretKey = kgen.generateKey();// 根据用户密码,生成一个密钥byte[] enCodeFormat = secretKey.getEncoded();// 返回基本编码格式的密钥SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥Cipher cipher = Cipher.getInstance("AES");// 创建密码器cipher.init(Cipher.DECRYPT_MODE, key);// 初始化为解密模式的密码器byte[] result = cipher.doFinal(content);return result; // 明文} catch (NoSuchAlgorithmException e) {e.printStackTrace();} catch (NoSuchPaddingException e) {e.printStackTrace();} catch (InvalidKeyException e) {e.printStackTrace();} catch (IllegalBlockSizeException e) {e.printStackTrace();} catch (BadPaddingException e) {e.printStackTrace();}return null;}

AES模式: AES/ECB/PKCS5Padding 不需要自己分组补位,相应也是相对CBC模式安全性较低。

二、解决源码

我的解决方案是自己写AES的秘钥生成128位的Key和使用Java Base64加密生成加密数据字符串;这样可以避免因为系统的随机数机制不同而不能加解密。

我的AES源码:


import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;/*** AES加密工具* <p>* 加密流程 AES -> BAse64* 解密流程 Base64 -> AES*/
public class AESUtil {//补充字典private final static String DIC = "1231g81f5456hhssg84h1f9q3f2x789s";// 加密public static String encrypt(String str, String key) {if (str == null || "".equals(str))return null;if (key == null || "".equals(key))return null;try {byte[] enCodeFormat = generateKey(key);// 返回基本编码格式的密钥,如果此密钥不支持编码,则返回SecretKeySpec skey = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器cipher.init(Cipher.ENCRYPT_MODE, skey);// 初始化为加密模式的密码器byte[] result = cipher.doFinal(str.getBytes("UTF-8"));// 加密return Base64.getUrlEncoder().encodeToString(result);} catch (Exception e) {LogUtil.e(e.toString());return null;}}// 解密public static String decrypt(String str, String key) {if (str == null || "".equals(str))return null;if (key == null || "".equals(key))return null;try {byte[] enCodeFormat = generateKey(key);// 返回基本编码格式的密钥SecretKeySpec skey = new SecretKeySpec(enCodeFormat, "AES");// 转换为AES专用密钥Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");// 创建密码器cipher.init(Cipher.DECRYPT_MODE, skey);// 初始化为解密模式的密码器byte[] base64 = Base64.getUrlDecoder().decode(str.getBytes("UTF-8"));byte[] result = cipher.doFinal(base64);return new String(result, "UTF-8"); // 明文} catch (Exception e) {LogUtil.e(e.getMessage());return null;}}/*** 自定义 秘钥补充** @param key* @return* @throws Exception*/private static byte[] generateKey(String key) throws Exception {byte[] dics = DIC.getBytes("UTF-8");byte[] bkeys = key.getBytes("UTF-8");byte[] keys = bkeys;int keylength = bkeys.length;if (keylength > 0 && keylength < 16) {keys = new byte[16];System.arraycopy(bkeys, 0, keys, 0, keylength);for (int i = keylength; i < 16; i++) {keys[i] = dics[i];}}if (keylength > 16 && keylength < 24) {keys = new byte[24];System.arraycopy(bkeys, 0, keys, 0, keylength);for (int i = keylength; i < 24; i++) {keys[i] = dics[i];}}if (keylength > 24 && keylength < 32) {keys = new byte[32];System.arraycopy(bkeys, 0, keys, 0, keylength);for (int i = keylength; i < 32; i++) {keys[i] = dics[i];}}if (keylength > 32) {keys = new byte[32];System.arraycopy(bkeys, 0, keys, 0, 32);}return keys;}

generateKey()的用于生成AES使用的128位秘钥;

注意:DIC这个秘钥补充字典 这个可以自己定义,但是一定要和java 后端一致。

加密解密时使用Base64我有相关的文章可以去参考一下:

自学Android开发 Java和Android SDK的Base64https://blog.csdn.net/Ym_quiet/article/details/123835335?spm=1001.2014.3001.5501

如果对您有一些意义,希望您给博主一些鼓励(点赞、关注、收藏),如果有错误欢迎大家评论。

自学Android开发 AES加密相关推荐

  1. 自学Android开发 关于OkHttp3的request和respond拦截打印Log

    一.需求和问题 在开发Android项目时,一定需要和后端对接网络请求,但在因为现在都JSON格式的数据结构,在数据字段前后不一致是Android端是无法判断是是字段错误还是数据本身没有值.所有在数据 ...

  2. 自学Android开发(一)

    自学Android开发咯(一) ------------------------------------ 很荣幸大家来看我的自学之路 现在刚好是2019的一月份中旬,也凑到我想学习Android的时间 ...

  3. android n AES加密,AndroidP AES 加密适配

    message Android N Didn't find class "org.apache.harmony.security.provider.crypto.SHA1PRNG_Secur ...

  4. 分享一下身边朋友自学android开发及找工作的那些事!【不足勿喷】

    写在前面 前不久身边一个朋友突然告诉我他把原来的工作辞掉了,我问他最近在干嘛,他说他最近两个月学了java及android然后花了1周时间找工作,我问他现在怎么样了.他说比不上我们身边这些10K-20 ...

  5. 分享一下身边朋友自学android开发及找工作的那些事!【不足勿喷】 1

    写在前面 前不久身边一个朋友突然告诉我他把原来的工作辞掉了,我问他最近在干嘛,他说他最近两个月学了java及android然后花了1周时间找工作,我问他现在怎么样了.他说比不上我们身边这些10K-20 ...

  6. android base64解密,android Base64 AES加密解密

    Android Base64代码如下: // 加密传入的数据是byte类型的,并非使用decode方法将原始数据转二进制,String类型的数据 使用 str.getBytes()即可 String ...

  7. aes c android ios,AES加密在iOS和Android中产生不同的结果

    尝试使用AES128算法加密样本数据,在 Android和iOS中使用CBC和PKCS7填充,但结果不同:( Android代码: private static final byte[] KEY = ...

  8. 2019 年美团点评高级 Android 开发寒冬跳槽涨薪经验掏心分享

    2019 年美团点评高级 Android 开发寒冬跳槽涨薪经验掏心分享 目录 个人简介 笔者的简要介绍 跳槽涨薪要考虑的方面有哪些? 你是正在拿着卖白菜的钱,操着卖白粉的心吗? 你真得觉得是时候跑路了 ...

  9. 我靠着这套学习视频+文档,自学Android从外卖小哥走到了头条

    5.受到一些心灵鸡汤的鼓励,比如什么种一颗树最好的时机是十年前,其次,就是现在! 辞职之后 我辞去工作,开始在家自学Android开发.主要的学习方式就是在网上看视频教程.那些视频教程,初级的基本上免 ...

最新文章

  1. 仅需10分钟:开启你的机器学习之路
  2. mysql备份实例攻略
  3. 谈中型项目下的编码技巧二
  4. linux中权限分离,linux多项目资源分离权限问题
  5. 如何用计算机辅助语言学习英语,计算机辅助下语言学习教学模式研究
  6. 为iptables增加layer7补丁(Linux2.6.25内核
  7. 语言设有某种十年期国债_孩子的语言敏感期,家长应该做些什么呢?
  8. Angular4.x+Ionic3 踩坑之路之打包时出现JAVASCRIPT HEAP OUT OF MEMORY的几种解决办法
  9. exec与xargs区别
  10. SAP License:SAP系统中的删除命令
  11. 决策树剪枝算法(二)
  12. python alembic which comes from SQLalchemy
  13. 八大黑盒测试方法总结【超详细】
  14. 【论坛项目】简单的论坛小项目-麻雀虽小,五脏俱全
  15. vegas Pro18.2021注册机补丁下载 如何做短视频基本参数设置及面板介绍
  16. 5G时代将给智能营销笔记本带来什么样的改变
  17. 如何将图片中的表格变成Excel?这几个操作很简单
  18. linux中cpu使用率命令,LINUX下查看CPU使用率的命令
  19. 2019年安徽大学ACM/ICPC实验室新生赛题解
  20. Ajax XHR响应

热门文章

  1. 管理小故事精髓 100例(转) 1
  2. QQ 引流引发的灰色地带产业
  3. 【小象学院】案例8——空气质量指数计算v7.0
  4. 电脑蓝屏c语言代码大全,Win10电脑卡机遇到蓝屏代码0xc000014c应该怎么办?
  5. 阿里巴巴 暑假实习 笔试题(2014年3月29日)
  6. 【计蒜客】等边三角形
  7. pandas的行列获取/pandas iloc和loc的使用/如何获取pandas的行和列
  8. BT下载不死!Magnet(磁力链接)开创网络BT2.0时代!!
  9. 实用的网站你值得来看
  10. 大数据技术——Hadoop3.X入门搭建+安装调优(1.入门)