AES-256-CBC-PKCS5Padding用c语言实现,并支持Android手机的调用
来源:互联网 发布:维旺迪收购育碧 知乎 编辑:程序博客网 时间:2024/05/21 17:54
参考:http://www.longdw.com/aes-256-cbc-c-android-pkcs5padding/
首先声明一下,以下所写的并不是深入研究AES算法,而是本人结合网络上高人写的文章,朋友的帮忙总结出了一套自认为更安全的支持Android的加密方式(不是原生的)。
公司给的需求是将密码和请求的URL地址采用AES加密,在网上找到了一位高人写的Object-c、C#、Java、Android都通用的版本,这里给上链接地址,通用AES加密版本(sample_java_aes256_imcore_net.zip,已经上传CSDN或者百度云),同时也直接附上附件,点击这里下载通用版本,在这里向原作者表示敬意!
可能大家都觉得奇怪,有现成的不用非要自己折腾用C语言来实现?这里我就要说下我的想法了,大家都知道Android中可以直接调用封装好的方法进行加密,但是这有个弊端,就是使用的密钥必须存储在Java代码中,大家都知道Java代码的安全性并不好,哪怕你打包混淆过别人都有办法看到里面的代码。后来我就放弃了把密钥(以下简称key)放在Java代码中的想法了。这个问题向我的好友@leepood也请教过,他给了我一些思路,然后我总结出了两套方案:1、key存储在c中,然后打包成so文件给Android调用;2、key存储在c中,Android端传递明文给c,然后通过c来加密并返回密文。后来决定使用第二种方案!这里要感谢下我的好友leepood。
然后就是接下来近4天的折腾了。参考了网上各种代码,c语言早忘光了(其实就是上学的时候没学好),看到什么char[],char* 脑袋立马就大了,但是没办法,还得硬着头皮去看。前前后后我算了下,至少尝试了网上提供的5套代码,没有一个是符合要求的,也就是快放弃的时候看到了pudn网站上提供的这套代码(pudn-AES.zip,已经上传CSDN或者百度云),没有积分的可以点击pudn-AES下载,这套代码注释很详细,以为看到希望了我经过一天多时间的测试发现不是代码的问题,而是这套代码完全不符合我的要求。下面我附上代码:
为了能稍微看懂些这套代码,至少是为了能修改代码适应我的需求吧,无意中搜索到了这篇文章,这里是文章的地址,感兴趣的也可以下载,我这里也提供下载地址,点击AES加密介绍(AES加密介绍.pdf,已经上传CSDN或者百度云)。由于目前C#端和IOS端采用的都是AES256并且是PKCS5Padding填充的方式,上面默认提供的是AES128方式的加密
根据上面的说明,修改代码Nk=8, Nr=14。然后测试代码,并对比Java原生的加密方式返回的字节流,一样的!!!Oh my god!皇天不负有心人啊!但高兴的还是太早了,输入的数据是16字节的还好,超过或不足16字节就是个坑啊!然后又看到上面pdf文章中写的这么一句话:
尼玛,这可怎么办!又是各种baidu,google,然后就看到了这篇本以为又遇到救星的文章,这里是文章地址。按文章中的说明:如果不足16字节的话我填充了0×06,我擦,还真可以。然后就是巨坑了,文章中说如果是16的倍数就填充0X16,而且也没说明如果大于16而不是16的倍数的情况。我就按他说的填充0X16!!!!怎么测试都跟Android端的字节流对不上。后来又换了几套代码还是不行!只能加密一组,后面填充16字节的数据怎么加密的都对不上。这套代码就这样废弃了,感兴趣的可以试下,代码应该是没问题的,后来发现(也就是我接下来要说的)填充的并不是0X16,而是0×10(十进制16),作者坑人不带商量的。后来找了一堆资料,有人说可以直接使用openssl中提供的AES加密方法,但是openssl这个开源c库太大了,我想单独把AES加密部分抠出来不太现实,关联的文件太多了,而且就一个小小的AES加密没必要用这么大的库。
又有放弃的念头了,然后就无所事事,萎靡不振,头昏脑胀的加了一个openssl的qq群,没抱任何希望的在里面发了条求助信息,过了一会一位好心的大哥回复了我,然后一番胡侃之后,在今天早上他给了我他写的代码。在这里真要感谢下这位大哥了!研究了下他的代码,然后他也指导了一番,终于在今天大功告成了!
大神提供的代码在这里下载(aes256_test.rar,已经上传CSDN或者百度云)。这套原生的支持输入3组(每组16个字节)明文数据就输出三组加密后的数据。而且没有填充功能,需要自己手动填充。说到填充这里需要补充几点知识,也是从网上看到的。如下:
算法/模式/填充 16字节加密后数据长度 不满16字节加密后长度
AES/CBC/NoPadding 16 不支持
AES/CBC/PKCS5Padding 32 16
AES/CBC/ISO10126Padding 32 16
AES/CFB/NoPadding 16 原始数据长度
AES/CFB/PKCS5Padding 32 16
AES/CFB/ISO10126Padding 32 16
AES/ECB/NoPadding 16 不支持
AES/ECB/PKCS5Padding 32 16
AES/ECB/ISO10126Padding 32 16
AES/OFB/NoPadding 16 原始数据长度
AES/OFB/PKCS5Padding 32 16
AES/OFB/ISO10126Padding 32 16
AES/PCBC/NoPadding 16 不支持
AES/PCBC/PKCS5Padding 32 16
AES/PCBC/ISO10126Padding 32 16
可以看到,在原始数据长度为16的整数倍时,假如原始数据长度等于16*n,则使用NoPadding时加密后数据长度等于16*n,其它情况下加密数据长度等于16*(n+1)。在不足16的整数倍的情况下,假如原始数据长度等于16*n+m[其中m小于16],除了NoPadding填充之外的任何方式,加密数据长度都等于16*(n+1);NoPadding填充情况下,CBC、ECB和PCBC三种模式是不支持的,CFB、OFB两种模式下则加密数据长度等于原始数据长度。
说到填充在这里也要说明下,不能被网络上复制来复制去的文章忽悠了。
1、如果输入的数据不足16个字节,需要补齐(填充)到16个字节,比如:10个字节就补齐6个6,11个字节就补齐5个5,以此类推;
2、如果输入的数据是16的整数倍个字节,需要在数据后面填充16个0×10(也可以是10进制的16);
3、如果输入的数据大于16且不是16的倍数,你需要把字符串补齐到16位,比如:如果少4位,就补充4个4, 如果少5位就补充5个5,少n位,补充n个n。
结合大神提供的代码和他的指点,然后修改了他的源码,自己写了一套适合在Android端使用的加密方式,可以输入任何长度的数据都可以返回。
源码下载。(jni_temp1.zip,已经上传CSDN或者百度云)
- AES-256-CBC-PKCS5Padding用c语言实现,并支持Android手机的调用
- C#, Java, PHP, Python和Javascript几种语言的AES加密解密实现【多种语言AES/CBC/PKCS5Padding通用加解密数据】
- AES-CBC-PKCS5Padding加密算法Java实现
- AES-CBC-PKCS5Padding加密算法Java实现
- AES/CBC/PKCS5Padding加解密
- java/php对应的AES/CBC/PKCS5Padding模式 加密解密
- Java与C/C++通用的“AES/ECB/PKCS5Padding”实现
- php AES/CBC/PKCS5Padding 与java对接
- AES/CBC/PKCS5Padding 对称算法加解密
- java加密之AES/CBC/PKCS5Padding
- android加密DESede/CBC/PKCS5Padding
- android加密DESede/CBC/PKCS5Padding
- android AES-256-CBC加密
- 用python实现aes ECB/CBC/CTR/CCM 的可执行文件
- java实现基于PKCS5Padding填充方式的AES加解密
- AES 128-bit ecb cbc 模式 C语言加密算法
- SM4 CBC模式加密的C语言实现
- AES PKCS5Padding
- [Leetcode]3Sum Closest
- linux中sysctl.conf文件常用参数中文说明
- jquery Dom操作
- 勿形人短,勿忌人能
- Android中时间日期类使用总结(Calendar和Date)
- AES-256-CBC-PKCS5Padding用c语言实现,并支持Android手机的调用
- android SharedPreferences
- 向ES6靠齐的Class.js
- DescriptionResourcePathLocationType 错误解决
- android使用appache httpclient混淆后错误排除总结
- vim配置文件(持续更新
- 再不能生动的并查集讲解
- 《读书笔记》系列4:MySQL开发者SQL权威指南
- 源于缺乏控制力的不安全感