安全加密算法与数据签名总结(1)

来源:互联网 发布:j罗 皇马 数据 编辑:程序博客网 时间:2024/04/30 11:28

常用的安全算法主要包括摘要算法、对称加密算法、非对称加密算法、信息编码等。

数字摘要
     数字摘要也称为消息摘要,它是一个唯一对应一个消息或文本的固定长度的值,它由一个单向Hash函数对消息进行计算而产生。如果消息在传递的途中改变了,接收者通过对收到的消息采用相同的Hash重新计算,新产生的摘要与原摘要进行比较,就可知道消息是否被篡改了,因此消息摘要能够验证消息的完整性。消息摘要采用单向Hash函数,将需要计算的内容“摘要”成固定长度的串,这个串也成为数字指纹。这个串有固定的长度,且不同的明文摘要成密文,其结果总是不同的(相对的,这个后面会介绍),而相同的明文其摘要必定一致。这样这串摘要便可成为验证明文是否是“真身”的“指纹”了。

待摘要串----->Hash函数----->摘要

     如果待摘要的关键字为k,Hash函数为f(x),则关键字k的摘要为f(x),若关键字k1不等于k2,而f(k1)=f(k2),这种现象称为Hash碰撞。一个Hash函数的好坏是由发生碰撞的概率决定的,如果攻击者能够轻易地构造出两个具有相同Hash值的消息,那么这样的Hash函数是很危险的。也可以认为摘要的长度越长算法也就越安全。由于数字摘要并不包含原文的完整信息,因此,要从摘要信息逆向得出待摘要的明文串,原则上几乎是不可能完成的任务。
     有关消息摘要的特点总结如下:
     (1)无论输入的消息有多长,计算出来的消息摘要的长度总是固定的。例如,应用MD5算法计算的摘要消息有128个比特位,而使用SHA-1算法计算出来的摘要消息有160个比特位。
     (2)一般只要输入的消息不同,对其进行摘要以后产生的摘要消息也不相同,但相同的输入必会产生相同的输出。这是一个好的消息摘要算法所需要具备的性质:输入改变了,输出也就改变了,两条相似的消息的摘要却大相径庭。好的摘要算法很难从中找到“碰撞”,虽然“碰撞“肯定是存在的。
     (3)由于消息摘要并不包含原文的完整信息,因此只能进行正向的信息摘要,而无法从摘要中恢复出原来的消息,甚至根本就找不到任何与原信息相关的信息。当然。可以采用暴力攻击的方法,尝试每一个可能的信息,计算其摘要,看看是否与已有的摘要相同。如果采用这种方式,最终肯定能恢复出摘要的消息,但是这种穷举的方式以目前的计算水平来看,需要消耗相当长的时间,因此被认为是不可能实现的。

1、MD5
MD5即Message Digest Algorithm5(信息摘要发5),是数字摘要算法的一种实现,用于确保信息传输完整性和一致性,摘要长度为128位。MD5是由MD4、3、2改进而来,主要增强了算法复杂度和不可逆。该算法因其普遍、稳定、快速的特点,被业界广泛使用。
Java的MD5算法的基本使用
public static byte[] encryptionMD5(String content){
   try {
      // Create MD5 Hash
      MessageDigest md = MessageDigest.getInstance("MD5");
     byte[] bytes = md.digest(content.getBytes("utf-8"));
      returnbytes;
   } catch (Exception e) {
      e.printStackTrace();
  }
   return "";
}
通过MessageDigest取得MD5摘要算法的实例,然后通过digest方法进行MD5的摘要。 
MD5算法生成的摘要串进行十六进制编码处理 

private static final char HEX_DIGITS[] = { '0''1''2''3''4''5',
   '6''7''8''9''a''b''c''d''e''f' };

private static String toHexString(byte[] b) { // String to byte
   StringBuilder sb = new StringBuilder(b.length 2);
   for (int i = 0i < b.lengthi++) {
      sb.append(HEX_DIGITS[(b[i] & 0xf0) >>> 4]);
     sb.append(HEX_DIGITS[b[i] & 0x0f]);
   }
   return sb.toString();
}

2、SHA
     SHA的全称是Secure Hash Algorithm,即安全散列算法。1993年美国国家标准和技术协会提出,1995年又发布了一个修订版,通常称之为SHA-1。SHA-1是基于MD4算法的,现在已成为公认的最安全的散列算法之一,并被广泛使用。
     SHA-1算法生成的摘要信息的长度为160位,由于生成的摘要信息更长,运算的过程更加复杂,在相同的硬件上,SHA-1的运行速度比MD5更慢但是也更安全。
Java的SHA-1 算法的基本使用
public static byte[] encryptionSHA1(String content){
   try 
      MessageDigest md = MessageDigest.getInstance("SHA-1");
     byte[] bytes = md.digest(content.getBytes("utf-8"));
      returnbytes;
   } catch (Exception e) {
      e.printStackTrace();
  }
   return "";
}
通过MessageDigest取得SHA-1摘要算法的实例,然后通过digest方法进行SHA-1的摘要。 
SHA-1算法生成的摘要串进行十六进制编码处理,通过SHA-1算法生成的摘要串为40位十六进制,转换成二进制位160位,明显比MD5算法生成的128位摘要要长。

3、十六进制编码
     计算机的计算采用是二进制的数据表示方法,而十六进制也是数据的一种表示方法,并且可以与二进制表示法不同的是,十六进制由0~9和A~F来进行表示,与十进制的对应关系是:0~9对应,A~F对应10~15。
Java的十六进制编码与解码的实现:
privatestaticString bytes2hex( byte[] bytes){
     StringBuilder hex =newStringBuilder();
     for(int i = 0; i < bytes.length; i++) {
              byteb = bytes[i];
          booleannegative =false;//是否为负数
          if(b < 0) negative =true;
          intinte = Math.abs(b);
          if(negative) inte = inte |0x80;
          //负数会转成整数(最高位的负号变成数值计算),在转十六进制
          String temp = Integer.toHexString(inte & 0xFF);
          if(temp.length() == 1) {
                   hex.append("0");
              }
          hex.append(temp.toLowerCase());
          }
          returnhex.toString();
    }

 privatestaticbyte [] hex2bytes(String hex) {
     byte[] bytes =newbyte [hex.length() /2];
     for(int i = 0; i < hex.length(); i = i +2) {
              String subStr = hex.substring(i, i+2);
              booleannegative =false;//是否为负数
              intinte = Integer.parseInt(subStr, 16);
              if(inte > 127) negative =true;
              if(inte == 128) {
                   inte = -128;
              }elseif (negative) {
                   inte = 0-(inte & 0x7F);
              }
          byteb = (byte)inte;
          bytes[i/2] = b ;
          }
          returnbytes;
    }
     每一个byte包含8位二进制数据,由于Java中没有无符号整型,因此8位中有一位为符号位,需要将符号位转换为对应的数值,然后在转换为对应的十六进制。8位二进制可以转换为2位十六进制,不足2位的进行补0,而解码时,需要先将符号位进行还原,再对数值进行转换,使用了Integer.parseInt(subStr,16)这个方法来对十六进制进行解析,将其转换为整型的数值,然后判断正负,计算出符号位,并将剩余的位还原为byte的数值。

4、Base64编码
     Base64是一种基于64个可打印字符表示二进制数据的方法,由于2的6次方等于64,所以每6位为一个单元,对应某个可打印字符,三个字节有24位,对应于4个Base64单元,即3个字节需要用4个可打印字符来表示。在Base64中的可打印字符包括字母A~Z、a~z\数字0~9,这样共有62个字符,此外两个可打印符号在不同的系统中而不同。
     很多人认为Base64是一种加密算法,并且将其当做加密算法来使用,而实际情况却并非这样,因为任何人只要得到Base64编码的内容,便可通过固定的方法,逆向得出编码之前的信息,Base64算法仅仅只是一种编码算法而已。它可以将一组二进制信息编码成可打印的字符,在网络上传输与展现。
Java的Base64算法的基本使用
  privatestaticString byte2base64(byte[] bytes) {
          returnBase64.encodeToString(bytes,Base64.DEFAULT);
    } 
   privatestaticbyte [] base642byte(String base64) {
          returnBase64.decode(base64, Base64. DEFAULT);
    }

5、彩虹表破解Hash算法
     彩虹表(Rainbow Table)法是一种破解哈希算法的技术,从原理上来说能够对任何一种Hash算法进行攻击。简单地说,彩虹表就是一张采用各种Hash算法生成的明文和密文的对照表,在彩虹表中,表内的每一条记录都是一串明文对应一种Hash算法生成的一串密文。我们得到一串加密字符,以及它采用的加密算法后,通过使用相关软件工具对彩虹表进行查找、比较、运算,能够迅速得出此加密字符串对应的明文,从而实现了对密文的破解。 




正因为彩虹表采用这种笨拙的方式,一一穷举存储明文和密文的所有组合,所以彩虹表非常的庞大,根据密文所对应明文的长度和复杂度(包括的字符类型:数字、字母、特殊字符等),常用到的彩虹表大小从几百MB到几十GB不等,当然理论上彩虹表的大小是可以无穷大的。

0 0
原创粉丝点击