SHA:안전 해시 알고리즘 요약 첨부 인 스 턴 스

머리말
체력 상 태 는 정신 상태 보다 먼저,습관 은 결심 보다 먼저,초점 은 취향 보다 먼저.
SHA 알고리즘 안내
1.1 개술
SHA(Secure Hash Algorithm,보안 해시 알고리즘 번역)는 미국 국가 안전 국(NSA)이 설계 하고 미국 국가 표준 기술 연구원(NIST)이 발표 한 일련의 암호 해시 함수 이다.공식 명칭 이 SHA 인 가족의 첫 번 째 멤버 는 1993 년 발표 됐다.그러나 사람들 은 후계자 와 헷 갈 리 지 않도록 비공 식 이름 SHA-0 을 지어 주 었 다.2 년 뒤 SHA-1,첫 번 째 SHA 의 후계자 가 발표 됐다.또한 네 가지 변형 도 있 는데 수출 의 범 위 를 향상 시 키 고 미세 디자인 을 변경 하 는 것 을 발표 한 적 이 있다.SHA-224,SHA-256,SHA-384 와 SHA-512(이런 것들 은 가끔 SHA-2 라 고도 부른다).
SHA 가족의 다섯 가지 알고리즘 은 각각 SHA-1,SHA-224,SHA-256,SHA-384,SHA-512 로 미국 국가 안전 국(NSA)이 설계 하고 미국 국가 표준 과 기술 연구원(NIST)이 발표 했다.미국의 정부 기준 이다.후 사 는 때로 SHA-2 라 고도 부른다.SHA-1 은 TLS 와 SSL,PGP,SSH,S/MIME,IPsec 를 포함 한 많은 안전 협정 에서 널리 사용 되 었 으 며 MD5(이전에 널리 사용 되 었 던 잡기 함수)의 후계자 로 여 겨 졌 다.그러나 SHA-1 의 안전성 은 현재 암호 학자 들 에 게 심각 한 의문 을 받 고 있다.아직 까지 SHA-2 에 대한 효과 적 인 공격 이 나타 나 지 않 았 지만 그 알고리즘 은 SHA-1 과 대체적으로 비슷 하 다.그래서 어떤 사람들 은 다른 대체 알고리즘 을 발전 시 키 기 시작 했다.
1.2 SHA 알고리즘 원리
SHA-1 은 데이터 암호 화 알고리즘 입 니 다.이 알고리즘 은 명문 을 받 은 다음 에 거 스 를 수 없 는 방식 으로 이 를 하나의(보통 더 작은)비밀문서 로 바 꾸 는 것 입 니 다.또한 입력 코드(예비 맵 또는 정보 라 고 함)를 취하 고 길이 가 비교적 짧 은 것 으로 간단하게 이해 할 수 있 습 니 다.비트 고정 출력 시퀀스 즉 해시 값(정보 요약 또는 정보 인증 코드 라 고도 함)의 과정 입 니 다.
단 방향 산열 함수 의 안전성 은 산열 값 이 발생 하 는 조작 과정 이 비교적 강 한 단 방향 성 을 가지 고 있다 는 데 있다.입력 시퀀스 에 비밀 번 호 를 삽입 하면 누구나 비밀 번 호 를 모 르 는 상태 에서 정확 한 해시 값 을 만들어 안전성 을 확보 할 수 없습니다.SHA 는 입력 흐름 을 각 512 비트(64 바이트)에 따라 블록 으로 나 누고 20 바이트 의 정보 인증 코드 나 정보 요약 이 라 고 불 리 는 출력 을 생 성 한다.
이 알고리즘 은 메시지 의 길 이 를 제한 하지 않 고 출력 은 160 비트 의 메시지 요약 입 니 다.입력 은 512 비트 의 그룹 으로 처 리 됩 니 다.SHA-1 은 거 스 를 수 없고 충돌 을 방지 하 며 좋 은 눈사태 효 과 를 가진다.
해시 알고리즘 을 통 해 디지털 서명 을 실현 할 수 있 습 니 다.디지털 서명 의 원 리 는 전송 할 명문 을 함수 연산(Hash)을 통 해 메시지 요약(서로 다른 명문 에 대응 하 는 서로 다른 메시지 요약)으로 바 꾸 고 메시지 요약 을 암호 화한 후에 명문 과 함께 수신 자 에 게 전송 하 는 것 입 니 다.수용 자 는 받 아들 인 명문 에 새로운 메시지 요약 과 발송 자가 보 낸 메시지 요약 을 복호화 하 는 것 을 비교 한 결과 명문 이 변경 되 지 않 았 음 을 일치 하 게 나타 내 고 명문 이 변경 되 었 음 을 일치 하지 않 으 면 명문 이 변경 되 었 음 을 나타 낸다.
1.3 SHA 알고리즘 응용
SHA 알고리즘 은 주로 정부 부처 와 자영 업자 가 민감 한 정 보 를 처리 하 는 데 사용 된다.예 를 들 어 지불 기구,은행 간 의 데이터 전송 은 SHA 해시 계산 을 사용 하여 암호 화 하 는 경우 도 있다.
SHA 안전 해시 알고리즘
보안 해시 알고리즘(영어:Secure Hash Algorithm,줄 임 말 SHA)은 암호 해시 함수 가족 입 니 다.
MD5 와 유사 하 게 보안 해시 알고리즘 은 문자열 에 따라 일정한 길이 의 요약 정 보 를 생 성 할 수 있 으 며,이 요약 정 보 는 되 돌 릴 수 없 으 며,서로 다른 문자열 의 요약 정보 가 같 을 확률 이 매우 낮다.
SHA 가족
SHA 에는 여러 가지 알고리즘 이 있 는데,일 부 는 이미 유행 이 지나 서 사용 하 는 것 을 추천 하지 않 고,일 부 는 안전 도가 높 지만 성능 이 떨어진다.
SHA1
길이 가 2^64 비트 이하 인 경우 SHA 1 은 160 비트 의 메시지 요약 을 생 성 합 니 다.
메시지 요약 에서 정 보 를 복원 할 수 없습니다.두 개의 서로 다른 소식 은 같은 메시지 요약 이 나 오지 않 습 니 다.(단,1x 10^48 분 의 1 의 확률 로 같은 메시지 요약 이 나 올 수 있 습 니 다.일반적으로 사용 할 때 무시 합 니 다)
디지털 인증서 의 서명 과 같은 정보 가 변경 되 었 는 지 확인 하 는 데 사용 할 수 있 습 니 다.
안전 하지 않 기 때문에 디지털 서명 인증 서 는 SHA 256 을 많이 사용 합 니 다.
SHA256
SHA 256 은 기능 적 으로 SHA 1 과 유사 하 며,일반적으로 정보 요약 에 도 사용 되 며,알고리즘 이 사용 하 는 해시 값 길 이 는 256 비트 이다.
디지털 인증서 의 서명,일반 데이터 의 서명,현재 유행 하 는 보안 해시 알고리즘
SHA384、SHA512
내용 이 약간 안전 하고 성능 도 소모 되 었 습 니 다.2019 년 8 월 20 일 까지 이 두 가지 알고리즘 은 모두 광범 위 하 게 추천 하지 않 았 고 시장 에서 추천 한 것 은 SHA 256 입 니 다.
안전성
현재 로 서 는 SHA 1 이 안전 하지 않 습 니 다.SHA 256 은 안전 합 니 다.
그러나 호환성 으로 볼 때 많은 시스템 이 SHA 1 을 지원 하지만 최신 은 SHA 256 을 요구 합 니 다.
자바 의 SHA
commons-codec 사용 하기
아파 치가 제공 하 는 jar 패키지 commons-codec 를 사용 할 수 있 습 니 다.
Maven 의존 은 다음 과 같다.

<dependency>
	<groupId>commons-codec</groupId>
	<artifactId>commons-codec</artifactId>
	<version>1.10</version>
</dependency>
코드 예
결 과 는 바이트 배열 로 16 진 전시 로 바 뀌 었 다.
Java

import org.apache.commons.codec.digest.DigestUtils;

public class ShaTest {

 public static void main(String [] args){
  String str="123";
  String sha1HexStr=DigestUtils.sha1Hex(str.getBytes());
  System.out.println("SHA1"+":"+sha1HexStr.length()+";"+sha1HexStr);

  String sha256HexStr=DigestUtils.sha256Hex(str.getBytes());
  System.out.println("SHA256"+":"+sha256HexStr.length()+";"+sha256HexStr);

  String sha384HexStr=DigestUtils.sha384Hex(str.getBytes());
  System.out.println("SHA384"+":"+sha384HexStr.length()+";"+sha384HexStr);

  String sha512HexStr=DigestUtils.sha512Hex(str.getBytes());
  System.out.println("SHA512"+":"+sha512HexStr.length()+";"+sha512HexStr);
 }
}
결과-16 진법 으로 전시
SHA1:40;40bd001563085fc35165329ea1ff5c5ecbdbbeef
SHA256:64;a665a45920422f9d417e4867efdc4fb8a04a1f3fff1fa07e998e86f7f7a27ae3
SHA384:96;9a0a82f0c0cf31470d7affede3406cc9aa8410671520b727044eda15b4c25532a9b5cd8aaf9cec4919d76255b6bfb00f
SHA512:128;3c9909afec25354d551dae21590bb26e38d53f2173b8d3dc3eee4c047e7ab1c1eb8b85103e3be7ba613b31bb5c9c36214dc9f14a42fd7a2fdb84856bca5c44c2
다음은 다른 네티즌 의 보충
자바 코드 구현 SHA 알고리즘

package cn.mars.app.txn.wanglian;
 
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 
 public class Sha1Util {
  /**
  * SHA1  
  * @param paramStr        
  * @return
  */
 public static String SHA1(String paramStr) {
  MessageDigest alg;
  String result = "";
  String tmp = "";
  try {
   alg = MessageDigest.getInstance("SHA-1");
   alg.update(paramStr.getBytes());
   byte[] bts = alg.digest();

   for (int i = 0; i < bts.length; i++) {
    tmp = (Integer.toHexString(bts[i] & 0xFF));
    if (tmp.length() == 1)
     result += "0";
    result += tmp;
   }
  } catch (NoSuchAlgorithmException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }

  return result;
 }
 
 public static void main(String[] args) {
  String sha1 = SHA1("111");
  
  System.out.println(sha1);
 }
}
암호 화 된 문자열 의 개 수 는 고정 되 어 있 습 니 다:40

package com.enterise.test;
public class SHA1 {
	
	private final int[] abcde = { 0x67452301,0xefcdab89,0x98badcfe,
	0x10325476,0xc3d2e1f0 };
	
	//         
	private int[] digestInt = new int[5];
	
	//               
	private int[] tmpData = new int[80];
	
	
	
	//	  
	public static void main(String[] args) {
		String param = "";
		System.out.println("   :" + param);
		System.out.println("length-->"+param.length());
		
		String digest = new SHA1().getDigestOfString(param.getBytes());
		System.out.println("   :" + digest);
		System.out.println("length-->"+digest.length());
	}
	
	//   sha-1  
	private int process_input_bytes(byte[] bytedata) {
	
		//      
		System.arraycopy(abcde,0,digestInt,0,abcde.length);
		
		//          , 10     
		byte[] newbyte = byteArrayFormatData(bytedata);
		
		//                
		int MCount = newbyte.length / 64;
		
		//                
		for (int pos = 0; pos < MCount; pos++) {
		
			//            16     ,    tmpData  16      
		for (int j = 0; j < 16; j++) {
			tmpData[j] = byteArrayToInt(newbyte,(pos * 64) + (j * 4));
		}
		
	//	      
		encrypt();
		}
		
		return 20;
	}
	
	//            
	private byte[] byteArrayFormatData(byte[] bytedata) {
		//  0  
		int zeros = 0;
		//       
		int size = 0;
		//       
		int n = bytedata.length;
		//  64      
		int m = n % 64;
		//     0       10     
			if (m < 56) {
				zeros = 55 - m;
				size = n - m + 64;
			} else if (m == 56) {
				zeros = 63;
				size = n + 8 + 64;
			} else {
				zeros = 63 - m + 56;
				size = (n + 64) - m + 64;
			}
		//            
		byte[] newbyte = new byte[size];
		//          
		System.arraycopy(bytedata,0,newbyte,0,n);
		//     Append       
		int l = n;
		//  1  
		newbyte[l++] = (byte) 0x80;
		//  0  
		for (int i = 0; i < zeros; i++) {
			newbyte[l++] = (byte) 0x00;
		}
		//       ,       8  ,   
		long N = (long) n * 8;
		byte h8 = (byte) (N & 0xFF);
		byte h7 = (byte) ((N >> 8) & 0xFF);
		byte h6 = (byte) ((N >> 16) & 0xFF);
		byte h5 = (byte) ((N >> 24) & 0xFF);
		byte h4 = (byte) ((N >> 32) & 0xFF);
		byte h3 = (byte) ((N >> 40) & 0xFF);
		byte h2 = (byte) ((N >> 48) & 0xFF);
		byte h1 = (byte) (N >> 56);
		
		newbyte[l++] = h1;
		newbyte[l++] = h2;
		newbyte[l++] = h3;
		newbyte[l++] = h4;
		newbyte[l++] = h5;
		newbyte[l++] = h6;
		newbyte[l++] = h7;
		newbyte[l++] = h8;
		
		return newbyte;
	}
	private int f1(int x,int y,int z) {
		return (x & y) | (~x & z);
	}
	
	private int f2(int x,int y,int z) {
		return x ^ y ^ z;
	}
	
	private int f3(int x,int y,int z) {
		return (x & y) | (x & z) | (y & z);
	}
	
	private int f4(int x,int y) {
		return (x << y) | x >>> (32 - y);
	}
	//
//	        
	private void encrypt() {
		for (int i = 16; i <= 79; i++) {
			tmpData[i] = f4(tmpData[i - 3] ^ tmpData[i - 8] ^ tmpData[i - 14]
			^ tmpData[i - 16],1);
		}
		
		int[] tmpabcde = new int[5];
		
		for (int i1 = 0; i1 < tmpabcde.length; i1++) {
			tmpabcde[i1] = digestInt[i1];
		}
		
		for (int j = 0; j <= 19; j++) {
			int tmp = f4(tmpabcde[0],5)
			+ f1(tmpabcde[1],tmpabcde[2],tmpabcde[3]) + tmpabcde[4]
			+ tmpData[j] + 0x5a827999;
			tmpabcde[4] = tmpabcde[3];
			tmpabcde[3] = tmpabcde[2];
			tmpabcde[2] = f4(tmpabcde[1],30);
			tmpabcde[1] = tmpabcde[0];
			tmpabcde[0] = tmp;
		}
		
		for (int k = 20; k <= 39; k++) {
			int tmp = f4(tmpabcde[0],5)
			+ f2(tmpabcde[1],tmpabcde[2],tmpabcde[3]) + tmpabcde[4]
			+ tmpData[k] + 0x6ed9eba1;
			tmpabcde[4] = tmpabcde[3];
			tmpabcde[3] = tmpabcde[2];
			tmpabcde[2] = f4(tmpabcde[1],30);
			tmpabcde[1] = tmpabcde[0];
			tmpabcde[0] = tmp;
		}
		
		for (int l = 40; l <= 59; l++) {
			int tmp = f4(tmpabcde[0],5)
			+ f3(tmpabcde[1],tmpabcde[2],tmpabcde[3]) + tmpabcde[4]
			+ tmpData[l] + 0x8f1bbcdc;
			tmpabcde[4] = tmpabcde[3];
			tmpabcde[3] = tmpabcde[2];
			tmpabcde[2] = f4(tmpabcde[1],30);
			tmpabcde[1] = tmpabcde[0];
			tmpabcde[0] = tmp;
		}
		
		for (int m = 60; m <= 79; m++) {
			int tmp = f4(tmpabcde[0],5)
			+ f2(tmpabcde[1],tmpabcde[2],tmpabcde[3]) + tmpabcde[4]
			+ tmpData[m] + 0xca62c1d6;
			tmpabcde[4] = tmpabcde[3];
			tmpabcde[3] = tmpabcde[2];
			tmpabcde[2] = f4(tmpabcde[1],30);
			tmpabcde[1] = tmpabcde[0];
			tmpabcde[0] = tmp;
		}
		
		for (int i2 = 0; i2 < tmpabcde.length; i2++) {
			digestInt[i2] = digestInt[i2] + tmpabcde[i2];
		}
		
		for (int n = 0; n < tmpData.length; n++) {
			tmpData[n] = 0;
		}
	}
	
	// 4         
	private int byteArrayToInt(byte[] bytedata,int i) {
		return ((bytedata[i] & 0xff) << 24) | ((bytedata[i + 1] & 0xff) << 16)
		| ((bytedata[i + 2] & 0xff) << 8) | (bytedata[i + 3] & 0xff);
	}
	
	
	//      4    
	private void intToByteArray(int intValue,byte[] byteData,int i) {
		byteData[i] = (byte) (intValue >>> 24);
		byteData[i + 1] = (byte) (intValue >>> 16);
		byteData[i + 2] = (byte) (intValue >>> 8);
		byteData[i + 3] = (byte) intValue;
	}
	
	//              
	private static String byteToHexString(byte ib) {
		char[] Digit = { '0','1','2','3','4','5','6','7','8','9','A',
		'B','C','D','E','F' };
		char[] ob = new char[2];
		ob[0] = Digit[(ib >>> 4) & 0X0F];
		ob[1] = Digit[ib & 0X0F];
		String s = new String(ob);
		
		return s;
	}
	
	//                
	private static String byteArrayToHexString(byte[] bytearray) {
		String strDigest = "";
		for (int i = 0; i < bytearray.length; i++) {
			strDigest += byteToHexString(bytearray[i]);
		}
		
		return strDigest;
	}
	//   sha-1  ,         
	public byte[] getDigestOfBytes(byte[] byteData) {
		process_input_bytes(byteData);
		byte[] digest = new byte[20];
		
		for (int i = 0; i < digestInt.length; i++) {
			intToByteArray(digestInt[i],digest,i * 4);
		}
		
		return digest;
	}
	
	//   sha-1  ,            
	public String getDigestOfString(byte[] byteData) {
		return byteArrayToHexString(getDigestOfBytes(byteData));
	}
 
}
여기 서 SHA:안전 해시 알고리즘 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 SHA 안전 해시 알고리즘 내용 은 저희 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 저 희 를 많이 사랑 해 주세요!

좋은 웹페이지 즐겨찾기