在编码中,经常会遇到md5和base64,比如说对于app本地密码的存储一般会进行MD5加密后存储,在http请求时,对于参数值进行base64 编码在进行传输,那么现在就来了解一下相关奥秘?
MD5:(参考文章)
- 不可逆加密算法,单向的——根据加密后的值几乎很难推断出原始字符串;
- 任意长度的数据,算出的MD5值长度都是固定的(即加密后的字符串长度一样)
- 弱碰撞性和高度离散,即修改一点点的原始字符串加密后的字符串就会变化很大
应用场景:
- 存储密码——数据库中存储的一般都是用户密码的MD5值或本地登陆密码进行md5加密(一般的用这种不可逆的算法加密就是不需要解密,比如app对原始密码加密传给服务器,服务器就以这个密码为标准进行存储,也不解密,这样每次登陆都是客户端加密,把密文传给服务器,服务器对比密文是否一致)
- 下载文件时,比较文件前后的md5,判断文件是否被修改
- 数字签名有时用md5进行签名
MD5 编程工具类:
private static byte[] hex = new byte[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
private static String convertToHexString(byte[] digests) {
byte[] md5String = new byte[digests.length * 2];
int index = 0;
for (byte digest : digests) {
md5String[index] = hex[(digest >> 4) & 0x0F];
md5String[index + 1] = hex[digest &0x0F];
index += 2;
}
return new String(md5String);
}
public static String encode(String rawString) {
String md5String = null;
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(rawString.getBytes());
md5String = convertToHexString(md5.digest());
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
if (null != md5String) {
return md5String.toUpperCase();
}
return md5String;
}
public static String getMD5(File file) {
FileInputStream fis = null;
try {
MessageDigest md = MessageDigest.getInstance("MD5");
fis = new FileInputStream(file);
byte[] buffer = new byte[2048];
int length = -1;
while ((length = fis.read(buffer)) != -1) {
md.update(buffer, 0, length);
}
byte[] b = md.digest();
return convertToHexString(b);//byteToHexString(b);
// 16位加密
// return buf.toString().substring(8, 24);
} catch (Exception ex) {
ex.printStackTrace();
return null;
} finally {
try {
if(fis != null){
fis.close();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
解析:主要是三步骤
1 进行初始化操作,需要指定算法
MessageDigest md5 = MessageDigest.getInstance("MD5");
MessageDigest 这个类是jdk内置的,还可以获取其他加密算法,比如sha1,sha256;
MessageDigest.getInstance("SHA-1");
2. 对摘要进行进行更新
md5.update(content.getByte[])
3. 计算消息摘要
md5.digest()
Base64 参考文章
Base64并不是安全领域的加密算法,其实Base64只能算是一个编码算法,对数据内容进行编码来适合传输。标准Base64编码解码无需额外信息即完全可逆,即使你自己自定义字符集设计一种类Base64的编码方式用于数据加密,在多数场景下也较容易破解。Base64编码本质上是一种将二进制数据转成文本数据的方案。
- 简单的编码,没有明文;
- 算法可逆
- 统一标准
常见的应用场景是:我们在发送http请求的时候,需要把key 和value 进行base64 编码在进行传输,这样避免了一些特殊字符,因为编码后的字符串只包含 [0-9a-zA-Z+/=] ,另外,我们在上传图片的时候也需要把图片二进制流转换为base64编码,这样才能上传。
base64工具类
public class Base64Help {
public static String encode(byte[] bytes){
return Base64.encodeToString(bytes, Base64.DEFAULT);
}
public static byte[] decode(String str) {
return Base64.decode(str, Base64.DEFAULT);
}
}