做者/Tamicjava
上节加固介绍了APi单纯Post用对称加密(Base64 为列子)加密方式。这样的加密方式仍是存在必定的风险,加密效率虽高,但易破解,本节将介绍怎么用非对称加密 来加解密okhttp的数据,本文採用RSA加密算法为栗子。git
对称加密是最传统的加密方式,比上非对称加密,缺乏安全性,但是它依然是用的比較多的加密方法。github
对称加密採用单密钥加密方式,不管是加密仍是解密都是用同一个密钥,即“一把钥匙开一把锁”。对称加密的优势在于操做简单、管理方便、速度快。它的缺点在于密钥在
网络传输中easy被窃听,每个密钥仅仅能应用一次。对密钥管理形成了困难。对称加密的实现形式和加密算法的公开性使它依赖于密钥的安全性。而不是算法的安全性。算法
对称加密原理以及对称加密算法浏览器
对称加密的核心——通讯两方共享一个密钥 通讯过程: A有明文m,使用加密算法E,密钥key。生成密文c=E(key,m); B收到密文c,使用解密算法D,密钥key。获得明文
m=D(key,c); 比喻: 对称加密是最直观,也是历史最久远的加密手段,类似于加锁和解锁,仅仅只是钥匙的个数很是多(~~2^100)。一我的穷其一辈子也试不全然部可能的钥匙
所以加密密钥可以从解密密钥中推算出来,同一时候解密密钥也可以从加密密钥中推算出来。安全
而在大多数的对称算法中,加密密钥和解密密钥是一样的。因此也称这样的加密算法为秘
密密钥算法或单密钥算法。网络
它要求发送方和接收方在安全通讯以前。商定一个密钥。dom
对称算法的安全性依赖于密钥,泄漏密钥就意味着不论什么人都可以对他们发送或接收的消息解
密,因此密钥的保密性对通讯性相当重要。ide
主要有DES算法。3DES算法,TDEA算法,Blowfish算法。RC5算法。IDEA算法。函数
非对称密算法是一种密钥的加密方法。
非对称加密算法需要两个密钥:公钥(publickey)和私钥(privatekey)。公钥与私钥是一对存在,假设用公钥对数据进行加密,仅仅实用相应的私钥才干解密;假设用密钥对数据进行加密。那么仅仅实用相应的公钥才干解密。因为加密和解密使用的是两个不一样的密钥,因此这样的算法叫做非对称加密算法。 非对称加密算法实现机密信息交换的基本过程是:甲方生成一对密钥并将当中的一把做为公用密钥向其余方公开;获得该公用密钥的乙方使用该密钥对机密信息进行加密后再发送给甲方;甲方再用本身保存的还有一把专用密钥对加密后的信息进行解密。
还有一方面,甲方可以使用乙方的公钥对机密信息进行签名后再发送给乙方;乙方再用本身的私匙对数据进行验签。
甲方仅仅能用其专用密钥解密由其公用密钥加密后的不论什么信息。 非对称加密算法的保密性比較好,它消除了终于用户交换密钥的需要。
非对称password体制的特色:算法强度复杂、安全性依赖于算法与密钥但是因为其算法复杂,而使得加密解密速度没有对称加密解密的速度快。对称password体制中仅仅有一种密钥,并且是非公开的,假设要解密就得让对方知道密钥。因此保证其安全性就是保证密钥的安全,而非对称密钥体制有两种密钥,当中一个是公开的,这样就可以不需要像对称password那样传输对方的密钥了。这样安全性就大了很是多。
列如 :支付宝的加密方式就採用非对称加密方式。支付宝会给客户提供支付宝证书,做为用户验证是不是来自支付宝的数据。防止第三方假冒支付宝,而客户手中持有私钥。用户支付宝发送的数据通过支付宝的公钥进项加密,则支付宝可以採用本身的的私钥进行解密。
工做过程
通俗点可以这么理解:
浏览器使用对称加密的钥匙对请求消息加密后传送给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);
完整的非对称加密过程
假如现在 你向支付宝 转帐(术语数据信息),为了保证信息传送的保密性、真实性、完整性和不能否认性,需要对传送的信息进行数字加密和签名,其传送过程为:
做者/Tamic
http://blog.csdn.net/sk719887916/article/details/65448628
阅读推荐