一、RSA算法
1.简介
RSA算法是一种非对称加密算法,也就是加密用的钥匙和解密用的钥匙,并不是同一把钥匙。非对称加密首先会创建两把钥匙,而这两把钥匙是成对的,分别称为公钥和私钥。加密时我们使用公钥进行加密,而在解密时必须使用私钥才能进行解密,这就是非对称加密算法。
假如使用非对称加密,甲(客户端)发送消息给乙(服务端),这时候乙(服务端)会预先创建好两把钥匙,私钥乙(服务端)自己保存好,然后把公钥发送给甲(客户端),甲(客户端)使用公钥对信息加密,然后传给乙(服务端),最后乙(服务端)使用自己的私钥对数据进行解密。
这个过程中,公钥还是有可能被第三者所截获,但是不同的是,这个第三者纵然得到了公钥,也无法解开密文,因为解密密文所需要的私钥从始至终一直在乙(服务端)的手里。因此这个过程是安全的。
二、AES算法
1.简介
AES算法是一种对称加密算法,原文经过了一把钥匙(密钥)加密后变成了密文,然后将密文传递给接收方,接收方再用这把钥匙(密钥)解开密文。这个过程中,加密和解密使用的是同一把钥匙,这种加密方式称为对称加密。
AES加密方式比DES加密更安全,但是速度比不上DES,但在不同运行环境下能保持良好的性能。
2.AES加密模式
2.1.AES一共有5种加密模式:
1.ECB(Electronic Code Book) 电码本模式
2.CBC(Cipher Block Chaining) 密码分组链接模式
3.CFB(Cipher FeedBack Mode) 密码反馈模式(较复杂)
4.OFB(Output FeedBack) 输出反馈模式(较复杂)
5.CTR(Counter) 计数器模式(不常见)
其中ECB.CBC.CTR为块加密模式;CFB.OFB为流加密模式
2.2.详细介绍
1.ECB电码本模式:
这种模式是将整个明文分成若干段相同的小段,然后对每一小段进行加密。

2.CBC密码分组链接模式:
这种模式是先将明文切分成若干小段,然后每一小段与初始块或者上一段的密文段进行异或后,再与密钥进行加密。

3.CTR计算器模式:
此模式不常见,在CTR模式中,有一个自增的算子,这个算子用密钥加密之后的输出和明文异或的结果得到密文,相当于一次一密。这种方式简单快速,安全可靠,而且可以并行加密,但是在计算器不能维持很长的情况下,密钥只能使用一次。

4.CFB密码反馈模式:

5.OFB输出反馈模式:

三、实例
1.背景
Android应用中通过对一个json数据进行加密后传输给后端进行解密验证
2.RSA方式
1.公钥加密
import android.util.Base64;//导包要用android的,如果用java的,会有换行导致的转义字符问题
public class RSAUtil{
//公钥
public static String publicKey="跟Java端同样的公钥";
/**
* 使用公钥加密
* @param data 待加密的数据
* @return
* @throws Exception
*/
public static String encryptByPublicKey(String data) throws Exception {
// 得到公钥对象
KeyFactory keyFactory = KeyFactory.getInstance("RSA");//SA算法
byte[] decodeKey = Base64.decode(publicKey.getBytes(), Base64.DEFAULT);
X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodeKey);
PublicKey pubKey = keyFactory.generatePublic(keySpec);
// 加密数据,加密方式:1.标准jdk的:RSA/None/PKCS1Padding;2.android的:RSA/None/NoPadding
Cipher cp = Cipher.getInstance("RSA/None/PKCS1Padding");
cp.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] encrypted = cp.doFinal(data.getBytes("UTF-8"));
return Base64.encodeToString(encrypted, Base64.DEFAULT);
}
}
public class A{
JSONObject reqbody = new JSONObject();
String encrypt = "";
try {
reqbody.put("name", "XXX");
encrypt = RSAUtil.encrypt(reqbody.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
将encrypt(加密后的json串)作为接口调用的参数传递到服务端进行解密
2.公钥分段加密
当加密的数据过长时,解密时会出现javax.crypto.IllegalBlockSizeException: Data must not be longer than 117 bytes的异常。因为RSA算法规定一次加密的数据不能超过生成密钥对时的keyLength/8-11,keyLength一般是1024个字节,则加密的数据不能超过117个字节;
https://cloud.tencent.com/developer/article/1730404
3.AES方式
public class AESUtil{
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding";
private static final String IVPARAMETER = "";//偏移量,可自行修改
private static final String CMCS_KEY = "";//key,可自行修改
/**
* 加密
* @param data 要加密的数据
*/
public static String encrypt(String data) throws Exception {
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
byte[] raw = CMCS_KEY.getBytes("UTF-8");
//获取密钥
SecretKeySpec skeySpec = new SecretKeySpec(raw, "AES");
IvParameterSpec iv = new IvParameterSpec(IVPARAMETER.getBytes());// 使用CBC模式,需要一个向量iv,可增加加密算法的强度
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, iv);
byte[] encrypted = cipher.doFinal(data.getBytes("UTF-8"));
return Base64.encodeToString(encrypted, Base64.DEFAULT);
}
}
public class A{
JSONObject reqbody = new JSONObject();
String encrypt = "";
try {
reqbody.put("name", "XXX");
encrypt = AESUtil.encrypt(reqbody.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
将encrypt(加密后的json串)作为接口调用的参数传递到服务端进行解密
参考:
RSA加密
https://www.cnblogs.com/badaoliumangqizhi/p/14166479.html
AES加密
https://www.jianshu.com/p/19b3c7acecb2