Android RSA加密对象数据
前几天说了手头项目用MD5和双向加密DES来进行加密的,因为产品是在不断的改造中完善的。考虑到DES和MD5加解密还是会存下一定的风险,于是产品一拍,不行,听你们说MD5加密是不安全的,咱们产品以后做大了的话肯定会有人对我们的产品进行攻击,所以我们还是用更安全一点的加解密方法吧。于是。。。。。
在接下来的几个小时里面,在针对各种加密方法的安全性和方案的可行性分析后,项目组确定用RSA算法对项目的IO数据进行加解密。于是又用到了一种加解密方法,于是又将它记下来,供大家分享和指正。
废话不多说,首先来跟度娘唠唠嗑。
度娘说:“1977年,三位数学家Rivest、Shamir 和 Adleman 设计了一种算法,可以实现非对称加密。这种算法用他们三个人的名字命名,叫做RSA算法。从那时直到现在,RSA算法一直是最广为使用的"非对称加密算法"。毫不夸张地说,只要有计算机网络的地方,就有RSA算法。这种算法非常可靠,密钥越长,它就越难破解。根据已经披露的文献,目前被破解的最长RSA密钥是768个二进制位。也就是说,长度超过768位的密钥,还无法破解(至少没人公开宣布)。因此可以认为,1024位的RSA密钥基本安全,2048位的密钥极其安全。” 。。。。好了够了,度娘,你这么啰嗦,我只是一名小小码农,不要跟我说质数相乘,不要跟我说欧拉定理,不要跟我说费马定理!!!!我只想安安静静的给我的数据加密和解密。
于是在Google大哥上面找了些代码片段,再经过同事们的整合,将传过去一大堆乱七八糟的字母解密成明文后,我知道,这礼拜六不用加班了。
上代码!Base64Utils.java:这个类的作用是将加密后的数据再进行一层加密,通过http传输进行前后台的数据IO。
public class Base64Utils { private static char[] base64EncodeChars = new char[] { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' }; /** * 加密 * * @param data * @return */ public static String encode(byte[] data) { StringBuffer sb = new StringBuffer(); int len = data.length; int i = 0; int b1, b2, b3; while (i < len) { b1 = data[i++] & 0xff; if (i == len) { sb.append(base64EncodeChars[b1 >>> 2]); sb.append(base64EncodeChars[(b1 & 0x3) << 4]); sb.append("=="); break; } b2 = data[i++] & 0xff; if (i == len) { sb.append(base64EncodeChars[b1 >>> 2]); sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]); sb.append(base64EncodeChars[(b2 & 0x0f) << 2]); sb.append("="); break; } b3 = data[i++] & 0xff; sb.append(base64EncodeChars[b1 >>> 2]); sb.append(base64EncodeChars[((b1 & 0x03) << 4) | ((b2 & 0xf0) >>> 4)]); sb.append(base64EncodeChars[((b2 & 0x0f) << 2) | ((b3 & 0xc0) >>> 6)]); sb.append(base64EncodeChars[b3 & 0x3f]); } return sb.toString(); } /** * 解密 * * @param str * @return */ public static byte[] decode(String str) { try { return decodePrivate(str); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } return new byte[] {}; } private static byte[] decodePrivate(String str) throws UnsupportedEncodingException { StringBuffer sb = new StringBuffer(); byte[] data = null; data = str.getBytes("US-ASCII"); int len = data.length; int i = 0; int b1, b2, b3, b4; while (i < len) { do { b1 = base64DecodeChars[data[i++]]; } while (i < len && b1 == -1); if (b1 == -1) break; do { b2 = base64DecodeChars[data[i++]]; } while (i < len && b2 == -1); if (b2 == -1) break; sb.append((char) ((b1 << 2) | ((b2 & 0x30) >>> 4))); do { b3 = data[i++]; if (b3 == 61) return sb.toString().getBytes("iso8859-1"); b3 = base64DecodeChars[b3]; } while (i < len && b3 == -1); if (b3 == -1) break; sb.append((char) (((b2 & 0x0f) << 4) | ((b3 & 0x3c) >>> 2))); do { b4 = data[i++]; if (b4 == 61) return sb.toString().getBytes("iso8859-1"); b4 = base64DecodeChars[b4]; } while (i < len && b4 == -1); if (b4 == -1) break; sb.append((char) (((b3 & 0x03) << 6) | b4)); } return sb.toString().getBytes("iso8859-1"); } }
其次就是RSAUtils.java类,这个类支持对字符串进行加密以及对某一个对象里面的所有属性通过遍历和反射机制进行加密。
public class RSAUtil {private static final String PUBLIC = ".***.***";//公钥文件名(约定以此结尾,作者对此部分进行了隐藏显示。ex:Android端对应的公钥文件名为android.public.***)private static final String PRIVATE = ".****.***";// 私钥文件名private static final String ENCRYPTKEY = PUBLIC;private static final String DECRYPTKEY = PUBLIC;private static String RSA = "RSA";private static final String ALGORITHM = "RSA/ECB/PKCS1Padding";//读取的公钥私钥缓存private static Map<String, Key> keyCache = new ConcurrentHashMap<String, Key>();//微型缓冲池private static Map<String, Cipher> cipherCache = new ConcurrentHashMap<String, Cipher>();private String client="android";private Context context;private Cipher encryptCipher;//由于Cipher是线程非安全,不能作为静态变量private Cipher decryptCipher;/*** 从字符串中加载私钥<br>* 加载时使用的是PKCS8EncodedKeySpec(PKCS#8编码的Key指令)。* * @param privateKeyStr* @return* @throws Exception*/private PrivateKey getPrivateKey(String privateKeyStr) throws Exception {byte[] buffer = Base64Utils.decode(privateKeyStr);PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(buffer);KeyFactory keyFactory = KeyFactory.getInstance(RSA);return keyFactory.generatePrivate(keySpec);}/*** 从字符串中加载公钥* * @param publicKeyStr* 公钥数据字符串* @throws Exception* 加载公钥时产生的异常*/private static PublicKey getPublicKey(String publicKeyStr) throws Exception {byte[] buffer = Base64Utils.decode(publicKeyStr);KeyFactory keyFactory = KeyFactory.getInstance(RSA);X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);return keyFactory.generatePublic(keySpec);}private String getKeyString(String keyName) throws Exception {InputStream is = context.getAssets().open(keyName);BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));String temp = null;StringBuffer sb = new StringBuffer();while ((temp = br.readLine()) != null) {sb.append(temp);}String keyString = sb.toString().replaceAll("-+[^-]+KEY-+", "");br.close();return keyString;}private Key getKey(String client, String type) throws Exception {String keyName = client + type;Key key = keyCache.get(keyName);if (key == null) {synchronized (RSAUtil.class) {key = keyCache.get(keyName);if (key == null) {String keyString = getKeyString(keyName);if (type.equals(PRIVATE)) {key = getPrivateKey(keyString);} else {key = getPublicKey(keyString);}keyCache.put(keyName, key);}}}return key;}public RSAUtil(Context context) {this.context = context;}public void destroy() {if (encryptCipher != null) {synchronized (RSAUtil.class) {String cipherName = client + ".encryptCipher";cipherCache.put(cipherName, encryptCipher);}}if (decryptCipher != null) {synchronized (RSAUtil.class) {String cipherName = client + ".decryptCipher";cipherCache.put(cipherName, decryptCipher);}}}protected void finalize() throws Throwable {destroy();super.finalize();}public byte[] encryptData(byte[] data) throws Exception {if (data == null) return null;//lazy initif (encryptCipher == null) {//try to load cachesynchronized (RSAUtil.class) {String cipherName = client + ".encryptCipher";encryptCipher = cipherCache.get(cipherName);cipherCache.remove(cipherName);}if (encryptCipher == null) {Key key = getKey(client, ENCRYPTKEY);encryptCipher = Cipher.getInstance(ALGORITHM);encryptCipher.init(Cipher.ENCRYPT_MODE, key);}}int blockSize = encryptCipher.getBlockSize();int outputSize = encryptCipher.getOutputSize(0);if (blockSize == 0) {//SunJCE returns 0blockSize = 117;outputSize = 128;}int pieces = (data.length - 1) / blockSize + 1;int rest = data.length % blockSize;byte[] result = new byte[pieces * outputSize];for (int p = 0; p < pieces; p++) {//last piece length = rest or blockSizeint length = ((p == pieces - 1) && rest != 0) ? rest : blockSize;encryptCipher.doFinal(data, p * blockSize, length, result, p * outputSize);}return result;}public byte[] decryptData(byte[] data) throws Exception {if (data == null) return null;//lazy initif (decryptCipher == null) {//try to load cachesynchronized (RSAUtil.class) {String cipherName = client + ".decryptCipher";decryptCipher = cipherCache.get(cipherName);cipherCache.remove(cipherName);}if (decryptCipher == null) {Key key = getKey(client, DECRYPTKEY);decryptCipher = Cipher.getInstance(ALGORITHM);decryptCipher.init(Cipher.DECRYPT_MODE, key);}}int blockSize = decryptCipher.getBlockSize();if (blockSize == 0) {//SunJCE returns 0blockSize = 128;}int pieces = data.length / blockSize;if (pieces == 0) throw new Exception("encrypted data is too short");ByteArrayOutputStream result = new ByteArrayOutputStream();for (int p = 0; p < pieces; p++) {result.write(decryptCipher.doFinal(data, p * blockSize, blockSize));}return result.toByteArray();}//字符串加密public String encryptString(String param) throws Exception {if (param == null) return null;byte[] encryptedByte = encryptData(param.getBytes("UTF-8"));return Base64Utils.encode(encryptedByte);}//字符串解密public String decryptString(String param) throws Exception {if (param == null) return null;byte[] decryptedByte = decryptData(Base64Utils.decode(param));return new String(decryptedByte, "UTF-8");}//对某一个对象进行加解密操作private <T> T opearteObject(T object, boolean encrypt, boolean withSuperClass) throws Exception {if (object == null) return null;Class<?> clazz = object.getClass();Field[] allFields = clazz.getDeclaredFields();while (withSuperClass && (clazz = clazz.getSuperclass()) != null) {Field[] newFields = clazz.getDeclaredFields();if (newFields.length == 0) continue;Field[] fields = allFields;allFields = new Field[fields.length + newFields.length];System.arraycopy(fields, 0, allFields, 0, fields.length);System.arraycopy(newFields, 0, allFields, fields.length, newFields.length);}for (Field field : allFields) {if (field.getType().equals(String.class)) {field.setAccessible(true);String value = (String) field.get(object);if (encrypt) {value = encryptString(value);} else {value = decryptString(value);}field.set(object, value);} else if (field.getType().equals(String[].class)) {field.setAccessible(true);String[] value = (String[]) field.get(object);for (int i = 0; i < value.length; i++) {if (encrypt) {value[i] = encryptString(value[i]);} else {value[i] = decryptString(value[i]);}}}}return object;}public <T> T encryptObject(T object) throws Exception {return opearteObject(object, true, false);}public <T> T decryptObject(T object) throws Exception {return opearteObject(object, false, false);}public <T> T encryptObjectWithSuperClass(T object) throws Exception {return opearteObject(object, true, true);}public <T> T decryptObjectWithSuperClass(T object) throws Exception {return opearteObject(object, false, true);}}
然后,就是在客户端使用这个加密方法了:
RSAUtil rsa=new RSAUtil(mContext);try {rsa.encryptObject(request);rsa.destroy();} catch (Exception e) {e.printStackTrace();}
对的,就是介么一小段代码,对request对象里所有的String类型的数据进行了加密操作。最后,还对改对象进行了一个destroy操作,以免占用太多的缓存。
然而,悲催的是,bob并不知道介个公钥和私钥是怎么产生的啊!!!在改代码的时候有见到客户端的私钥,但是公钥说是不给我。。我介么善良的一个银你觉得我会泄露秘钥么。。。算啦,再去其他地方找找秘钥的生成吧。
转载于:https://www.cnblogs.com/BobAdmin/p/4943255.html
Android RSA加密对象数据相关推荐
- Android RSA 加密
没想到被Android里的RSA加密折腾了几个小时,主要还是自己对RSA加密的原理不了解,然后网上相关的资料也少. 使用AndroidUtilCode工具类中的EncryptUtils.encrypt ...
- Android RSA加密解密的 工具类的使用
RSA 比较特殊,我们首先要生成私钥和公钥,然后在加密的时候,使用私钥加密,在解密的时候使用公钥解密. //RSA 的初始化,获得私钥和密钥public void rsaInit(){try {Key ...
- android rsa加密工具类,GitHub - Lerist/encrypt: Android 加密解密工具包。
Encrypt(加密工具) 字符串,byte[],文件等对象的加密和解密工具集合,包含了多种加密方案. 加密类型 摘要 相关方法 简单加密 换一种编码格式 Base64Util 单向加密 只能加密,不 ...
- android RSA加密
这个RSA加密其实自己也没有完全弄清楚,只是在网上自己找了一些资料,也是为了记录自己的代码. 概述 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但 ...
- Android RSA加密解密
转载: http://blog.csdn.net/bbld_/article/details/38777491 概述 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素 ...
- Android RSA加密解密,用于和服务器交互时的请求
概述 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困 难,因此可以将乘积公开作为加密密钥,即公钥,而两个大素数 ...
- java android rsa加密解密_Android RSA加密解密
转载 http://blog.csdn.net/bbld_/article/details/38777491 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事实:将两个大素数相乘十 ...
- android rsa加密工具类,android RSA加密
释放双眼,带上耳机,听听看~! 这个RSA加密其实自己也没有完全弄清楚,只是在网上自己找了一些资料,也是为了记录自己的代码. 概述 RSA是目前最有影响力的公钥加密算法,该算法基于一个十分简单的数论事 ...
- RSA加密超长数据 前端js 作为参考
偏前端 + rsa加解密 + jsencrypt.min.js–(新增超长字符分段加解密) 复制代码 <html>2 <head>3 <title>JavaScri ...
最新文章
- WinCE6.0 修改开机Logo方法集锦(二)
- R语言vtreat包自动处理dataframe的缺失值、使用分组的中位数来标准化数据列中每个数据的值(和中位数表连接并基于中位数进行数据标化)、计算数据列的中位数或者均值并进行数据标准化
- 安卓打开rpm文件_微信文件如何分享到QQ?教你一招,不管什么手机都能行
- 炫彩界面库使用方法问题记录
- nodejs中使用RabbitMq消息中心系统的方式
- 前端浏览器兼容知识点整理
- python --- 使用socket创建tcp服务
- Eclipse GlassFish 5.1就在这里!
- UISlider 滑块控件—IOS开发
- Mvvm 前端数据流框架精讲
- MySql (二)入门语句和基本操作
- 选股公式 成功率测试 软件,通达信股票软件选股公式,99%的成功率,你还等什么?...
- 在Python中安装了graphvize还出现报错:ExecutableNotFound: failed to execute ‘dot‘, make sure the Graphviz execut
- 【深度学习】眼底图像之视盘和黄斑分割的探索
- 如何在html中播放.flv格式的视频【vue和普通html皆可用】
- java中级程序员面试题_51CTO下载-JAVA中级程序员面试题
- 计算机网络英语作文150字,微信投票的英语,写一篇关于网络投票看法的英语作文150字左右...
- 相关性分析和相似度计算
- 上交所几大业务平台简介
- 谷歌 火狐 主页被篡改,修改文件名解决
热门文章
- PHP中$_SERVER[QUERY_STRING]函数
- SharePoint 2010 新体验5 - Office Web Applications
- Java多线课程,java多线程课程.doc
- 一些重要的 XML DOM 方法概述
- chrome动态ip python_简单python代码实现模拟浏览器操作
- php linux脚本文件,Unix/Linux中如何直接执行PHP脚本文件?
- java 泛型多重限制_Java泛型:有界类型参数中的多重继承
- 关于列表标签的一些使用(有序,无序,自定义列表)
- linux环境调用gsoap,Linux下gSOAP的使用 (c++)
- lookup函数和vlookup_5个实用案例告诉你,为什么说Lookup函数比vlookup更简单