1.MD5,SHA1加密校验
MD5,SHA1等加密算法我们通常不用来做加密,因为解密成本非常大,我们一般用MD5,SHA1等用来做文件校验,唯一性校验等功能。常见的场景如防止别人恶意篡改我们的APP软件,这个时候我们可以对文件做MD5或SHA1算法校验,生成一个唯一值。用户通过这两个值可以判断这个APP是否为官方渠道。算法如下:
/**
* MD5加密.
*
* @param stream 待加密数据
* @param type 加密类型,如MD5,SHA-1, SHA-224, SHA-256, SHA-384, SHA-512
* @return 加密后的数据
*/
public static byte[] md5(InputStream stream, String type) {
try {
MessageDigest md5 = MessageDigest.getInstance(type);
DigestInputStream dis = new DigestInputStream(stream, md5);
byte[] buffer = new byte[4096];
while (dis.read(buffer) > 0) ;
return dis.getMessageDigest().digest();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
如果只是对普通文本信息做加密校验的话,就不需要DigestInputStream
,直接使用md5.digest(data);
就可以了。
2.AES对称加密
对称加密算法有DES, 3DES, AES等算法,在对称加密中,加密和解密的密钥相同,一般用于安全性不是很高的信息加密,其中DES加密算法出现的较早,随着互联网技术的发展,破解DES算法的成本越来越低,已经达不到最初的加密效果,于是又提出了AES对称加密算法,AES加密方式为字节代替,行移位,列混淆和轮密钥加。代码如下:
/**
* AES加密解密,填充方式为CBC,补码为PKCS5Padding,注意密钥和偏移量必须是16个字节.
*
* @param encrypt true为加密,false为解密
* @param data 待加密解密数据
* @param key 加密解密密钥,必须16个字节
* @param iv 偏移量,必须16个字节
* @return 返回加密或解密后的数据
*/
public static byte[] aes(boolean encrypt, byte[] data, byte[] key, byte[] iv) {
if (data != null || key != null && iv != null && key.length == 16 && iv.length == 16) {
SecretKeySpec spec = new SecretKeySpec(key, "AES");
try {
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
int mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
cipher.init(mode, spec, new IvParameterSpec(iv));
return cipher.doFinal(data);
} catch (GeneralSecurityException e) {
e.printStackTrace();
}
}
return null;
}
其中的填充方式有ECB, CBC, CTR, CFB, OFB。除ECB方式外,其它方式都需要一个16字节的偏移量,补码方式为PKCS5Padding,PKCS7Padding,ZEROPadding,ISO10126和ANSIX923。其中PKCS5Padding和PKCS7Padding的填充方式效果一样PKCS5Padding常用于Android加密,PKCS7Padding常用于iOS加密。
3.RSA非对称加密
在有些场景下对对数据的安全性要求比较就,这个时候我们就不能用对称加密将密钥暴露出来。我们可以通过RSA非对称加密来完成这样的功能,RSA加密分公钥加密解密和私钥加密解密,通常我们将公钥公布在外对信息加密,将私钥放在服务器进行解密,这样别人通过抓包的方式获取到数据也无法解密,具体代码如下:
/**
* 生成RSA密钥对,密钥长度为512/1024/2048
*
* @param keyLength 密钥长度
* @return 返回密钥对
*/
public static KeyPair generateRSAKeyPair(int keyLength) {
try {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(keyLength);
return kpg.genKeyPair();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
/**
* RSA公钥加密解密.
*
* @param encrypt true为加密,false为解密
* @param data 待加密数据
* @param key 公钥
* @return 加密或解密后的数据
*/
public static byte[] rsaPublicKey(boolean encrypt, byte[] data, byte[] key) {
X509EncodedKeySpec spec = new X509EncodedKeySpec(key);
try {
KeyFactory factory = KeyFactory.getInstance("RSA");
PublicKey publicKey = factory.generatePublic(spec);
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
int mode = encrypt ? Cipher.ENCRYPT_MODE : Cipher.DECRYPT_MODE;
cipher.init(mode, publicKey);
return cipher.doFinal(data);
} catch (GeneralSecurityException e) {
e