详解详解Android端与端与JavaWeb传输加密(传输加密(DES+RSA))
主要介绍了详解Android端与JavaWeb传输加密(DES+RSA),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
一、加密介绍一、加密介绍
本文采用对称式加密算法DES和非对称式加密算法RSA结合做数据传输加密的方式。
先说一下对称式加密 DES:对称式加密即使用单钥密码加密的方法,信息的加密和解密使用同一个秘钥,这种方式也称为单秘钥加密。所谓对称就是指加密和解密使用的是同一个秘钥!
常用的对称加密有:DES、IDEA、RC2、RC4、SKIPJACK、RC5、AES算法等。
与对称加密算法不同,非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥 (privatekey)。公开密钥与私有密钥是一对,如果用公开密钥对数据进行加密,只有用对应的私有密钥才能解
密;如果用私有密钥对数据进行加密,那么只有用对应的公开密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法。
RSA 公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前
为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。 RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公
开作为加密密钥。
二、RSA密钥生成二、RSA密钥生成
RSA密钥采用OpenSSL协议进行生成,本文仅简单生成公钥和私钥,如有其它需要可以通过CA证书进行密钥的生成
1、1、OpenSSL安装安装
http://slproweb.com/products/Win32OpenSSL.html
请自行选择32位64位进行下载安装
2、打开工作空间2、打开工作空间
打开OpenSSL安装目录下的bin,运行OpenSSL.exe进入OpenSSL工作空间
3、密钥生成3、密钥生成
①、私钥生成(生成位置位于bin目录下)
genrsa -out rsa_private_key.pem 1024
openssl随机生成了一份私钥,加密长度是1024位。加密长度是指理论上最大允许”被加密的信息“长度的限制,也就是明文的长度限制。随着这个参数的增大(比方说2048),允许的明文长度也会增加,
但同时也会造成计算复杂度的极速增长。一般推荐的长度就是1024位(128字节)
JAVA需要使用的私钥需要经过PKCS#8编码,PHP程序不需要
当前私钥格式需要转换为pkcs#8的格式,命令为:
pkcs8 -topk8 -inform PEM -in pkcs8_rsa_private_key.pem -outform PEM -nocrypt
②、公钥生成
rsa -in rsa_private_key.pem -out rsa_public_key.pem -pubout
至此,RSA+DES相关前期准备工作完成
三、三、Android端配置端配置
本文主要针对数据传输过程进行加密,采取加密Json字符串完成整个加密过程,由此,需要统一传输参数为"data=********&sign="*******************"的格式,如有其它需求请自行更改。
由于本项目网络框架采用Retrofit+OkHttp的实现方式,所以对参数进行加密的过程由OkHttp拦截器来实现
public class EncryptionInterceptor implements Interceptor {
private Context mContext;
public EncryptionInterceptor(Context context) {
this.mContext = context;
}
@Override
public Response intercept(@NonNull Chain chain) throws IOException {
Request request = chain.request();
RequestBody oldBody = request.body();
Buffer buffer = new Buffer();
if (oldBody != null) {
oldBody.writeTo(buffer);
}
String strOldBody = buffer.readUtf8();
Map<String, String> map = new HashMap<>();
String dataByte = URLDecoder.decode(strOldBody.substring(5), "utf-8");
try {
//获取DES的key
byte[] desKey = DESCoder.initKey();
//DES加密数据
byte[] encrypt = DESCoder.encrypt(dataByte.getBytes(), desKey);
map.put("data", parseByte2HexStr(encrypt));
//RSA加密
RSAEncrypt rsaEncrypt = new RSAEncrypt();
InputStream inputStream = mContext.getResources().getAssets().open("rsa_public_key.pem");
//rsa设置公钥
rsaEncrypt.loadPublicKey(inputStream);
//rsa加密DES的key
byte[] rsaData = rsaEncrypt.encrypt(rsaEncrypt.getPublicKey(), desKey);
map.put("sign", parseByte2HexStr(rsaData));
} catch (Exception e) {
e.printStackTrace();
}
FormBody body = new FormBody.Builder().add("data", map.get("data")).add("sign", map.get("sign")).build();
request = request.newBuilder().header("Content-Type", body.contentType().type()).header("Content-Length", String.valueOf(body.contentLength())).method(request.method(), body).build();
return chain.proceed(request);
}
/**
* 将二进制转换成16进制
*
* @since v1.0
*/
private static String parseByte2HexStr(byte buf[]) {
StringBuilder sb = new StringBuilder();
for (byte aBuf : buf) {
String hex = Integer.toHexString(aBuf & 0xFF);
if (hex.length() == 1) {
hex = '0' + hex;
}
sb.append(hex.toUpperCase());
}
return sb.toString();
}
/**
* 按照key排序得到参数列表字符串
*
* @param paramValues 参数map对象