注意:本篇文章是本人阅读相关文章所写下的总结,方便以后查阅,所有内容非原创,侵权删。
本篇文章内容来自于:
Android安全加密:消息摘要Message Digest
Android数据加密之MD5加密
目录
- 什么是数字摘要
- 数字摘要实现代码(MD5、SHA通用)
- 附录
1.什么是数字摘要
消息摘要(Message Digest)又称为数字摘要(Digital Digest)。它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash加密函数对消息进行作用而产生。如果消息在途中改变了,则接收者通过对收到消息的新产生的摘要与原摘要比较,就可知道消息是否被改变了。
消息摘要后的结果是固定长度,无论你的数据有多大,哪怕是只有一个字节或者是一个G 的文件,摘要后的结果都是固定长度。
数字摘要常用算法
MD5、SHA、CRC 等 都是哈希Hash算法
数字摘要使用场景
- 对用户密码进行md5 加密后保存到数据库里
- 软件下载站使用消息摘要计算文件指纹,防止被篡改
- 数字签名
- 百度云,360网盘等云盘的妙传功能用的就是sha1值
- Eclipse和Android Studio开发工具根据sha1值来判断v4,v7包是否冲突
- 据说银行的密码使用的就是MD5加密(因为MD5具有不可逆性)
病毒查杀,把每个病毒文件或apk进行MD5后得到一个特征码,拿着特征码去跟病毒数据库对比,特征码一致说明该文件是病毒 - Git版本控制也使用到了sha1
2. 数字摘要实现代码(MD5、SHA通用)
具体代码实现
String content = "见到放得开的2323adfd";
////常用算法:MD5、SHA、CRC
MessageDigest digest = MessageDigest.getInstance("MD5");
byte[] rel = digest.digest(content.getBytes());
//消息摘要的结果一般都是转换成16 进制字符串形式展示
String hex = Hex.encode(rel);
//MD5 结果为16 字节(128 个比特位)、转换为16 进制表示后长度是32 个字符
//SHA 结果为20 字节(160 个比特位)、转换为16 进制表示后长度是40 个字符
Log.d("xl", hex);
//输出结果
D/xl: 321a9629a83c94392d52d9a0f2ca0cb4
字节数组与16进制字符串转换工具Hex
/**
* 字节数组与16进制字符串转换工具
*/
public class Hex {
private static final char[] HEX_CHAR = { '0', '1', '2', '3', '4', '5', '6',
'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* 字节数组转换成16进制字符串
*
* @param bytes
* @return
*/
public static String encode(byte[] bytes) {
if (bytes == null || bytes.length == 0) {
return null;
}
StringBuffer sb = new StringBuffer(bytes.length * 2);
// 27对应的十六进制为1b,对应的二进制是00011011
// 取高位和低位:00011011-》0001,1011-》1,b
for (int i = 0; i < bytes.length; ++i) {
// 取高位:跟0xf0做与运算后再右移4位
int high = (bytes[i] & 0xf0) >> 4;// 0xf0: 11110000
// 取低位:跟0x0f做与运算
int low = bytes[i] & 0x0f;// 0x0f: 00001111
// 字符映射
sb.append(HEX_CHAR[high]).append(HEX_CHAR[low]);
}
return sb.toString();
}
/**
* 16进制字符串转换为字节数组
*
* @param hex 16进制字符
* @return
*/
public static byte[] decode(String hex) {
if (hex == null || hex.length() == 0) {
return null;
}
// 16进制转byte,长度减半,"1b"-->27
int len = hex.length() / 2;
byte[] result = new byte[len];
String highStr = null;
String lowStr = null;
int high = 0;
int low = 0;
for (int i = 0; i < len; i++) {
// 高位值
highStr = hex.substring(i * 2, i * 2 + 1);// "1b"的高位为"1"
high = Integer.parseInt(highStr, 16);// 高位转为10进制
// 低位值
lowStr = hex.substring(i * 2 + 1, i * 2 + 2);// "1b"的低位为"b"
low = Integer.parseInt(lowStr, 16);// 低位转为10进制
// 合计值
result[i] = (byte) ((high << 4) + low);// 相当于:(高位*16) + 低位
}
return result;
}
}
3. 附录
MD5解密网站http://www.cmd5.com/
为了提高MD5 加密的安全性,减少密文被反向解密的可能性,应尽量将密码的长度设置的长一些,另外也可以将密码进行多次加密,这样可以保护用户的隐私安全