常见加密解密和URL编解码
Base64
概念:
基于64个可打印字符,用于表示二进制数据,使用的字符包括大小写拉丁字母各26个、数字10个、加号+和斜杠/,共64个字符,等号=用来作为后缀用途
2^6=64 因此一个可打印字符由6bit来表示
3个字符(3
8)可由4个可打印字符表示(4
6)
作用:
常用于用来表示二进制数据
MD5(Message Digest algorithm 5)
概念:
一种摘要算法,非对称加密,不可逆(因为会将原文部分信息丢失),长度固定(128位) 16进制表示
哈希算法的一种
作用:
不用来做安全性加密,因为可以被碰撞出来 常用来进行文件校验 防止文件被篡改或替换
碰撞:
不同的原数据可能得到相同的哈希值 此为碰撞 而若校验该哈希值,则可能被碰撞得到而导致不安全
彩虹表:
对一些常见的数值(如123456)MD5得到的值保存到一个巨大的表中,便于拿到哈希值进行反查原数据
密钥salt
在加密算法中主要被设计用来防止“字典攻击”。字典攻击也是一种穷举的暴力破解法。字典中会假设一定数量的密码值,攻击者会尝试用这些密码来解密密文。Salt是在密钥导出之前在密码末尾引入的随机字节,它使这类攻击变得非常困难。
初始化向量IV
在加密算法中起到的也是增强破解难度的作用。在加密过程中,如果遇到相同的数据块,其加密出来的结果也一致,相对就会容易破解。加密算法在加密数据块的时候,往往会同时使用密码和上一个数据块的加密结果。因为要加密的第一个数据块显然不存在上一个数据块,所以这个初始化向量就是被设计用来当作初始数据块的加密结果。
数字信封
采用对称加密算法加密数据,非对称加密算法加密对称密钥的方式解决了以上的问题
SSL
SHA-1 SHA-256
类似MD5 只是比MD5安全 更难被碰撞
SHA-1长度为160位 SHA-256长度为256位
对称加密
使用相同密钥进行加密和解密
优点:速度快 适用于大数据 大文件
缺点:但需要相同密钥,密钥传输过程中可能被截获
一、DES算法
二、AES算法
IV向量:是否考虑方向性 如0000000000000000 不考虑方向
长度: 有128 192 256位 MCRYPT_RIJNDAEL_256
模式:MCRYPT_MODE_ECB(分块加密) CBC CFB等模式
解密秘钥:key
填充: 是否末尾填充 NoPadding PKCS5Padding等
kotlin aes解密:
fun decryptAes(inpute: ByteArray): String {
// 创建cipher对象
val cipher = Cipher.getInstance("AES/ECB/NoPadding")
// 初始化cipher
// 通过秘钥工厂生产秘钥
val keySpec = SecretKeySpec(key.toByteArray(), "AES")
cipher.init(Cipher.DECRYPT_MODE, keySpec)
// 加密、解密
val encrypt = cipher.doFinal(inpute)
return String(encrypt)
}
非对称加密
A自己生成公钥和私钥 将公钥给到B B通过公钥对内容进行加密,然后A通过秘钥进行解密
优点: 安全 不会暴露私钥
缺点;速度慢
一、RSA加密
核心:难以将一个数拆分成两个大的素数(质数)
URLEncode RawURLEncode
英文数字不处理 处理特殊符号(空格、换行、等于) 和 中文字符
两者唯一区别是对于空格字符的处理
urlencode处理成“+”,rawurlencode处理成“%20”
加密工具类
public class MD5 {
public static String md5(String content) {
byte[] hash;
try {
// MessageDigest.getInstance("MD5") 通过信息摘要单例的构造函数获取信息摘要对象md5
// content.getBytes("UTF-8") 获取字符串的字节数组.
// .digest()对字节数组进行摘要,得到摘要字节数组:
hash = MessageDigest.getInstance("MD5").digest(content.getBytes("UTF-8"));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("NoSuchAlgorithmException",e);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("UnsupportedEncodingException", e);
}
// 把摘要数组中的每一个字节转换成16进制,并拼在一起就得到了MD5值.
StringBuilder hex = new StringBuilder(hash.length * 2);
for (byte b : hash) {
if ((b & 0xFF) < 0x10){
hex.append("0");
}
hex.append(Integer.toHexString(b & 0xFF));
}
return hex.toString();
}
}