Retrofit/OkHttp API接口加固技术实践(下)
作者/Tamic
http://blog.csdn.net/sk719887916/article/details/65448628
imageMogr2/auto-orient/strip%7CimageView2/2/w/1240" alt="" title="">
上节加固介绍了APi单纯Post用对称加密(Base64 为列子)加密方式。这样的加密方式还是存在一定的风险,加密效率虽高,但易破解,本节将介绍怎么用非对称加密 来加解密okhttp的数据,本文採用RSA加密算法为栗子。
对称加密
对称加密是最传统的加密方式,比上非对称加密,缺少安全性,可是它依然是用的比較多的加密方法。
对称加密採用单密钥加密方式,不论是加密还是解密都是用同一个密钥,即“一把钥匙开一把锁”。对称加密的优点在于操作简单、管理方便、速度快。它的缺点在于密钥在
网络传输中easy被窃听,每一个密钥仅仅能应用一次。对密钥管理造成了困难。对称加密的实现形式和加密算法的公开性使它依赖于密钥的安全性。而不是算法的安全性。
对称加密原理以及对称加密算法
对称加密的核心——通信两方共享一个密钥 通信过程: A有明文m,使用加密算法E,密钥key。生成密文c=E(key,m); B收到密文c,使用解密算法D,密钥key。得到明文
m=D(key,c); 比喻: 对称加密是最直观,也是历史最久远的加密手段,相似于加锁和解锁,仅仅只是钥匙的个数非常多(~~2^100)。一个人穷其一生也试不全然部可能的钥匙
因此加密密钥能够从解密密钥中推算出来,同一时候解密密钥也能够从加密密钥中推算出来。
而在大多数的对称算法中,加密密钥和解密密钥是同样的。所以也称这样的加密算法为秘
密密钥算法或单密钥算法。
它要求发送方和接收方在安全通信之前。商定一个密钥。
对称算法的安全性依赖于密钥,泄漏密钥就意味着不论什么人都能够对他们发送或接收的消息解
密,所以密钥的保密性对通信性至关重要。
主要有DES算法。3DES算法,TDEA算法,Blowfish算法。RC5算法。IDEA算法。
非对称加密
非对称密算法是一种密钥的加密方法。
非对称加密算法须要两个密钥:公钥(publickey)和私钥(privatekey)。公钥与私钥是一对存在,假设用公钥对数据进行加密,仅仅实用相应的私钥才干解密;假设用密钥对数据进行加密。那么仅仅实用相应的公钥才干解密。由于加密和解密使用的是两个不同的密钥,所以这样的算法叫作非对称加密算法。 非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将当中的一把作为公用密钥向其他方公开;得到该公用密钥的乙方使用该密钥对机密信息进行加密后再发送给甲方;甲方再用自己保存的还有一把专用密钥对加密后的信息进行解密。
还有一方面,甲方能够使用乙方的公钥对机密信息进行签名后再发送给乙方;乙方再用自己的私匙对数据进行验签。
甲方仅仅能用其专用密钥解密由其公用密钥加密后的不论什么信息。 非对称加密算法的保密性比較好,它消除了终于用户交换密钥的须要。
非对称password体制的特点:算法强度复杂、安全性依赖于算法与密钥可是由于其算法复杂,而使得加密解密速度没有对称加密解密的速度快。对称password体制中仅仅有一种密钥,而且是非公开的,假设要解密就得让对方知道密钥。所以保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,当中一个是公开的,这样就能够不须要像对称password那样传输对方的密钥了。这样安全性就大了非常多。
列如 :支付宝的加密方式就採用非对称加密方式。支付宝会给客户提供支付宝证书,作为用户验证是否是来自支付宝的数据。防止第三方假冒支付宝,而客户手中持有私钥。用户支付宝发送的数据经过支付宝的公钥进项加密,则支付宝能够採用自己的的私钥进行解密。
工作过程
- 1.A要向B发送信息,A和B都要产生一对用于加密
- 2.A的私钥保密,A的公钥告诉B。B的私钥保密。B的公钥告诉A。
- 3.A要给B发送信息时,A用B的公钥加密信息。由于A知道B的公钥。
- 4.A将这个数据发给B(已经用B的公钥加密消息)。
- 5.B收到这个数据后后,B用自己的私钥解密A的消息。其他全部收到这个报文的人都无法解密,由于仅仅有B才有B的私钥。
通俗点能够这么理解:
- 浏览器向server发出请求,询问对方支持的对称加密算法和非对称加密算法;server回应自己支持的算法。
- 浏览器选择两方都支持的加密算法,并请求server出示自己的证书;server回应自己的证书。
- 浏览器随机产生一个用于本次会话的对称加密的钥匙,并使用server证书中附带的公钥对该钥匙进行加密后传递给server。server为本次会话保持
- 该对称加密的钥匙。第三方不知道server的私钥,即使截获了数据也无法解密。非对称加密让不论什么浏览器都能够与server进行加密会话。
浏览器使用对称加密的钥匙对请求消息加密后传送给server,server使用该对称加密的钥匙进行解密;server使用对称加密的钥匙对响应消息加密后传送给浏览器,浏览器使用该对称加密的钥匙进行解密。第三方不知道对称加密的钥匙,即使截获了数据也无法解密。对称加密提高了加密速度
数字证书
数字证书就是互联网通讯中标志通讯各方身份信息的一串数字,提供了一种在Internet上验证通信实体身份的方式。数字证书不是数字身份证,而是身份认证机构盖在数字身份证上的一个章或印(或者说加在数字身份证上的一个签名)。
它是由权威机构——CA机构。又称为证书授权(Certificate Authority)中心发行的。人们能够在网上用它来识别对方的身份。
数字证书绑定了公钥及其持有者的真实身份,它相似于现实生活中的居民身份证,所不同的是数字证书不再是纸质的证照。而是一段含有证书持有者身份信息并经过认证中心审核签发的电子数据,广泛用在电子商务和移动互联网中。。
通俗讲就是车管所会给每一个车辆进行认证颁发车牌。通过车牌我们能够查到全部车辆和驾驶员的信,二数字证书就辨别唯一身份,支付宝等的数字证书就是公开的。这不是支付宝自己决定。而是由国际组织认证,这样无论是哪个用户首先就能够依据浏览器返回的证书辨别支付宝的真伪。
数字签名
数字签名用来,保证信息传输的完整性、发送者的身份认证、防止交易中的抵赖发生。
数字签名是将摘要信息用发送者的私钥加密。与原文一起传送给接收者。接收者仅仅实用发送者的公钥才干解密被加密的摘要信息,然后用HASH函数对收到的原文产生一个摘要信息,与解密的摘要信息对照。假设同样,则说明收到的信息是完整的,在传输过程中没有被改动,否则说明信息被改动过,因此数字签名能够验证信息的完整性。假设中途数据被纂改或者丢失。
那么对方就能够依据数字签名来辨别是否是来自对方的第一手信息数据。
数字签名是个加密的过程,数字签名验证是个解密的过程。
參数加解密
首先。Android中生成了对称密钥:
public static SecretKeySpec generateSymmetric() {
// Set up secret key spec for 128-bit AES encryption and decryption
SecretKeySpec sks = null;
try {
SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");
sr.setSeed("any data used as random seed".getBytes());
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(128, sr);
sks = new SecretKeySpec((kg.generateKey()).getEncoded(), "AES");
System.out.println("AES KEY: " + sks);
} catch (Exception e) {
Log.e(TAG, "AES secret key spec error");
}
return sks;
}
然后将SecretKeySpec转换为Base64字符串格式:
public static String ConvertSymmetricKeyToString(SecretKeySpec key) {
String symmetric_key = null;
symmetric_key = Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
return symmetric_key;
}
调用函数:
SecretKeySpec symmKey = generateSymmetric();
newSymmetricKeyString = CreateEncryptedXml.ConvertSymmetricKeyToString(symmKey);
用SecretKeySpec加密数据:
private static String encryptDataWithSymmetricKey (SecretKeySpec symmKey, String data) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
// encryption
byte[] toBeCiphred = data.getBytes("UTF-8");
String encryptedData = null;
try {
Cipher c = Cipher.getInstance("AES");
c.init(Cipher.ENCRYPT_MODE, symmKey);
byte[] encodedBytes = c.doFinal(toBeCiphred);
System.out.println("BYTE STRING (ASYMM): " + encodedBytes);
encryptedData = Base64.encodeToString(encodedBytes, Base64.DEFAULT);
} catch (Exception e) {
Log.e(TAG, "AES encryption error");
throw new RuntimeException(e);
}
return encryptedData;
}
encryptedData = encryptDataWithSymmetricKey(symmKey, text);
使用拦截器:
然后将字符串秘密AES密钥和加密的数据(用这个AES密钥加密)使用okhttp使POST请求。字符串密钥使用的是RSA加密。
public class EncryptionInterceptor implements Interceptor {
private static final String TAG = EncryptionInterceptor.class.getSimpleName();
private static final boolean DEBUG = true;
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
RequestBody oldBody = request.body();
Buffer buffer = new Buffer();
oldBody.writeTo(buffer);
String strOldBody = buffer.readUtf8();
MediaType mediaType = MediaType.parse("text/plain; charset=utf-8");
String strNewBody = encryptDataWithSymmetricKey(symmKey, text);
RequestBody body = RequestBody.create(mediaType, strNewBody);
request = request.newBuilder().header("Content-Type", body.contentType().toString()).header("Content-Length", String.valueOf(body.contentLength())).method(request.method(), body).build();
return chain.proceed(request);
}
}
在server端能够解密(从RSA)秘密AES密钥,并得到它的字符串表示。在client(Android)和server端(server)上是一样的。
使用这个字符串AES密钥解密数据
String encryptionMethod = "AES-128-CBC";
//decryptedAESKey is an Android AES SecretKeySpec converted to string
//in Android the string key was base64_encoded, 服务端解密 decode
String secretHash = base64Decode(decryptedAESKey);
// Decrypt
String decryptedMessage = opensslDecrypt(base64Decode(encryptedData), encryptionMethod, secretHash);
总结
完整的非对称加密过程
假如如今 你向支付宝 转账(术语数据信息),为了保证信息传送的保密性、真实性、完整性和不可否认性,须要对传送的信息进行数字加密和签名,其传送过程为:
- 1.首先你要确认是否是支付宝的数字证书,假设确觉得支付宝身份后。则对方真实可信。能够向对方传送信息,
- 2.你准备好要传送的数字信息(明文)计算要转的多少钱。对方支付宝账号等。
- 3.你 对数字信息进行哈希运算。得到一个信息摘要(client主要职责);
- 4.你 用自己的私钥对信息摘要进行加密得到 你 的数字签名,并将其附在数字信息上。
- 5.你 随机产生一个加密密钥,并用此password对要发送的信息进行加密(密文)。
- 6.你用 支付宝的公钥对刚才随机产生的加密密钥进行加密,将加密后的 DES 密钥连同密文一起传送给支付宝。
- 7.支付宝收到 你 传送来的密文和加密过的 DES 密钥,先用自己的私钥对加密的 DES 密钥进行解密,得到 你随机产生的加密密钥;
- 8.支付宝 然后用随机密钥对收到的密文进行解密,得到明文的数字信息,然后将随机密钥抛弃;
- 9.支付宝 用你 的公钥对 你的的数字签名进行解密。得到信息摘要;
- 10.支付宝用同样的哈希算法对收到的明文再进行一次哈希运算,得到一个新的信息摘要。
- 11.支付宝将收到的信息摘要和新产生的信息摘要进行比較。假设一致,说明收到的信息没有被改动过。
- 12 确定收到信息。然后进行向对方进行付款交易,一次非对称密过程结束。在这后面的流程就不属于本次非对称加密的范畴,算支付宝个人的自我流程,也就是循环以上过程。
作者/Tamic
http://blog.csdn.net/sk719887916/article/details/65448628
阅读推荐
Retrofit/OkHttp API接口加固技术实践(下)的更多相关文章
- Retrofit/Okhttp API接口加固技术实践(上)
作者:Tamic 地址:http://blog.csdn.net/sk719887916/article/details/61914609 写这篇文章,我纠结了非常久,究竟是属于app安全系列,还是属 ...
- php后台对接ios,安卓,API接口设计和实践完全攻略,涨薪必备技能
2016年12月29日13:45:27 关于接口设计要说的东西很多,可能写一个系列都可以,vsd图都得画很多张,但是由于个人时间和精力有限,所有有些东西后面再补充 说道接口设计第一反应就是r ...
- atitit.基于http json api 接口设计 最佳实践 总结o7
atitit.基于http json api 接口设计 最佳实践 总结o7 1. 需求:::服务器and android 端接口通讯 2 2. 接口开发的要点 2 2.1. 普通参数 meth,p ...
- ApsNetCore打造一个“最安全”的api接口
Authentication,Authorization 如果公司交给你一个任务让你写一个api接口,那么我们应该如何设计这个api接口来保证这个接口是对外看起来"高大上",&qu ...
- 关于vue2用vue-cli搭建环境后域名代理的http-proxy-middleware解决api接口跨域问题
在vue中用http-proxy-middleware来进行接口代理,比如:本地运行环境为http://localhost:8080但真实访问的api为 http://www.baidu.com这时我 ...
- Atitit.gui api自动化调用技术原理与实践
Atitit.gui api自动化调用技术原理与实践 gui接口实现分类(h5,win gui, paint opengl,,swing,,.net winform,)1 Solu cate1 Sol ...
- 从api接口获取数据-okhttp
首先先介绍下api接口: API:应用程序接口(API:Application Program Interface) 通常用于数据连接,调用函数提供功能等等... 从api接口获取数据有四种方式:Ht ...
- 利用Metaweblog技术的API接口同步到多个博客网站(详细)
很早就有这个想法:自己有时候会用到多个博客,有些博客在一个网站上写完之后,要同步到其他博客网站,自己只能复制粘贴,感觉特别没意思,复制粘贴的麻木了.一直在想有哪些技术能实现一次写博,多站同步.最近网上 ...
- China .NET Conf 2019-.NET技术架构下的混沌工程实践
这个月的8号.9号,个人很荣幸参加了China.NET Conf 2019 , 中国.NET开发者峰会,同时分享了技术专题<.NET技术架构下的混沌工程实践>,给广大的.NET开发小伙伴介 ...
随机推荐
- Git GUI中文乱码问题解决方法
使用Git GUI的查看代码的时候,会出现中文乱码: 在乱码的区域点击鼠标右键,选择Encoding,然后选择Unicode(UTF-8),乱码问题解决:
- JMeter测试工具中的参数化使用[函数助手]
下面是我使用JMeter测试工具对某项目中的一个http接口进行测试时的配置参数,使用到了JMeter的随机函数: 在发送POST请求时,需要发送json格式的数据,其中使用到JMeter的" ...
- FFmpeg Basics学习笔记(2)
帧率 fps的概念 帧率,单位FPS(frame per second), 用于衡量视频每秒的处理帧数,对于编码器而言说明编码器在1s的编码的速度,通常可以使用一帧的编码时间倒数简单计算:对于解码器而 ...
- LeetCode: Jump Game II 解题报告
Jump Game II Given an array of non-negative integers, you are initially positioned at the first inde ...
- pandas简单应用
机器学习离不开数据,数据分析离不开pandas.昨天感受了一下,真的方便.按照一般的使用过程,将pandas的常用方法说明一下. 首先,我们拿到一个excel表,我们将之另存为csv文件.因为文件是实 ...
- fzu2157(树形dp)
http://acm.fzu.edu.cn/problem.php?pid=2157 这是一道很水的树形dp吧,本来不想写它的题解的,不过比赛的时候,队友说要我做这个题目,但是由于我感觉另一个题目可以 ...
- linux下Anaconda安装使用Tensorflow
# linux下Anaconda安装使用Tensorflow ### 环境------------------------------ Ubuntu 18.04 ### 环境准备----------- ...
- WCF 服务应用程序与 服务库之间的区别
简单理解, WCF服务库,可以认为是一个包含WCF服务以及契约定义的类库.这儿库还不能直接运行,你可以在其他项目里引用,在宿主里启用托管这个库. 而WCF应用程序,是一个可以执行的程序,它有独立的进程 ...
- [Note] Collaborator vs. the Factory
Collaborator-vs-he-Factoryhtml, body {overflow-x: initial !important;}html { font-size: 14px; } body ...
- vs2010中TargetName与链接器输出名不一致
当出现解决方案生成正确,但是无法执行.exe文件,即系统无法找到指定文件时,提示有:MSB8012: TargetName(,,,) 与 Linker 的 OutputFile 属性(,,,)不匹配. ...