MySQL에서 SHA1 해시 값 저장


160

SHA1 해시의 결과를 MySQL 데이터베이스에 저장하려고 할 때 발생하는 간단한 질문이 있습니다.

해시 결과를 저장 하는 VARCHAR 필드의 길이는 얼마 입니까?


9
sha1을 googled 한 경우 운이 좋은 느낌을 받으면 항상 160 비트 인 wikipedia에 있어야합니다.
Tim Matthews

답변:


315

내가 사용하는 것이 VARCHAR가변 길이 데이터가 아닌 고정 길이 데이터. SHA-1 값은 항상 160 비트 길이이므로 고정 길이 필드의 길이에 대해 추가 바이트를VARCHAR 낭비 합니다 .

그리고 나는 SHA1돌아 오는 가치를 저장하지 않을 것 입니다. 문자 당 4 비트 만 사용하므로 160/4 = 40자가 필요합니다. 그러나 문자 당 8 비트를 사용하는 경우 160/8 = 20 자 길이의 필드 만 필요합니다.

내가 추천 그래서 당신이 사용 BINARY(20)하고 UNHEX기능은 변환하는 SHA1바이너리 값입니다.

나는에 대한 스토리지 요구 사항을 비교 BINARY(20)하고 CHAR(40).

CREATE TABLE `binary` (
    `id` int unsigned auto_increment primary key,
    `password` binary(20) not null
);
CREATE TABLE `char` (
    `id` int unsigned auto_increment primary key,
    `password` char(40) not null
);

백만 건의 기록 binary(20)은 44.56M, char(40)64.57M이 걸립니다. InnoDB엔진.


2
PostgreSQL에서 이것은 bytea 필드를 사용하는 것으로 해석됩니다.
mvexel

해결책은 훌륭하지만 16 진수 sha1과 함께 char (40)을 사용하는 또 다른 요점이 있습니다. 이는 훨씬 널리 사용되며 응용 프로그램 코드에는 변환 문제가 적습니다.
Arthur Kushman

2
phpmyadmin 사용자를위한 참고 사항. 해시를 바이너리로 저장하면 phpmyadmin은이 문자열을 16 진 문자열로 표시하지만 pma는 제공된 "검색 탭"에서이를 사용할 수 없습니다. UNHEX()SQL에 수동으로 추가하는 경우에만 작동합니다 .
Timo Huovinen

2
@Gumbo bytea에 가변 수의 바이트를 저장할 수 있습니다. bytea 유형의 저장 요구 사항을 참조하고 있습니다. "1 또는 4 바이트 + 실제 이진 문자열"입니다. "1 또는 4"는 varchar와 마찬가지로 문자열을 끝내기 위해 0 바이트를 사용할 수 없으므로 저장된 데이터의 길이 일 수 있습니다. 즉, 매뉴얼에 명시되어 있지는 않지만 바이 테아에 최대 2 ^ (8 * 4) 또는 4+ 기가 바이트를 저장할 수 있습니다. postgresql.org/docs/9.0/static/datatype-binary.html postgres 데이터베이스에 해시를 저장하는 것은 약간 또는 bytea 열로 가장 작을 것입니다 .
Viktor

2
dev.mysql.com/doc/refman/5.5/en/… 암호화 기능의 결과를 저장할 때 성능 및 저장 정보를 제공합니다
Clocker


11

이 블로그에서 가져온 참조 :

아래는 필요한 비트 크기와 함께 해싱 알고리즘의 목록입니다.

  • MD5 = 128 비트 해시 값.
  • SHA1 = 160 비트 해시 값
  • SHA224 = 224 비트 해시 값.
  • SHA256 = 256 비트 해시 값
  • SHA384 = 384 비트 해시 값
  • SHA512 = 512 비트 해시 값.

CHAR (n)이 필요한 하나의 샘플 테이블을 작성했습니다.

CREATE TABLE tbl_PasswordDataType
(
    ID INTEGER
    ,MD5_128_bit CHAR(32)
    ,SHA_160_bit CHAR(40)
    ,SHA_224_bit CHAR(56)
    ,SHA_256_bit CHAR(64)
    ,SHA_384_bit CHAR(96)
    ,SHA_512_bit CHAR(128)
); 
INSERT INTO tbl_PasswordDataType
VALUES 
(
    1
    ,MD5('SamplePass_WithAddedSalt')
    ,SHA1('SamplePass_WithAddedSalt')
    ,SHA2('SamplePass_WithAddedSalt',224)
    ,SHA2('SamplePass_WithAddedSalt',256)
    ,SHA2('SamplePass_WithAddedSalt',384)
    ,SHA2('SamplePass_WithAddedSalt',512)
);

10
제발, 제발 , 제발 사실이 같은 암호를 저장하지 않습니다.
Berry M.

베리, 왜 당신의 이유를 설명 할 수 있습니까? 세부 사항
Anvesh

4
암호의 간단한 해시를 저장하면 소금에 절인 (허용 된) 암호 해시를 사용하는 것보다 데이터베이스가 손상된 경우 암호를 "추출"하는 것이 훨씬 쉽습니다. 추천 독서 : paragonie.com/blog/2016/02/how-safely-store-password-in-2016
matt

2
@BerryM. 1 년 후이 글을 읽고, 누군가 암호에 대해 이야기하고 있거나 사람들이 여전히 간단한 해시를 사용하여 인증 데이터를 저장한다고 생각하지 않았습니다. 그러나 그들은 : D
Rohit Hazra

6

sha1의 출력 크기는 160 비트입니다. 160/8 == 20 자 (8 비트 문자를 사용하는 경우) 또는 160/16 = 10 (16 비트 문자를 사용하는 경우)입니다.


8 비트 이진 문자를 가정합니다. 16 진수로 저장된 경우 40 자.
Tyzoid

3

따라서 길이는 10 개의 16 비트 문자와 40 진수 사이입니다.

어쨌든 저장할 형식을 결정하고 해당 형식에 따라 필드를 고정 크기로 만듭니다. 그렇게하면 낭비되는 공간이 없습니다.


2

사용자의 해시를 항상 저장하지 않는 경우 (예 : 계정 인증 / 로그인 URL을 잊어 버린 경우) VARCHAR을 계속 사용할 수 있습니다. 사용자가 로그인 정보를 인증 / 변경 한 후에는 해시를 사용할 수 없어야하며 이유가 없어야합니다. 임시 해시-> 사용자 연결을 저장하기 위해 별도의 테이블을 만들 수 있지만 삭제할 수는 있지만 대부분의 사람들이 이것을 귀찮게 생각하지는 않습니다.


2

sha1 열에 색인이 필요한 경우 성능상의 이유로 CHAR (40)을 제안합니다. 필자의 경우 sha1 열은 전자 메일 확인 토큰이므로 방문 페이지에서 쿼리는 토큰으로 만 입력됩니다. 이 경우 INDEX가있는 CHAR (40)이 최선의 선택이라고 생각합니다. :)

이 방법을 사용하려면 $ raw_output = false를 그대로 두십시오.


1
BINARY (20)를 색인화하지 않는 이유는 무엇입니까? 그 크기가 절반만큼 크지 않습니까?
nickdnk

글쎄요 ~ 5 년 전이지만 나는 여전히 약간의 부하를 가하는 16 진수를 풀어야한다고 생각한다고 생각합니다 (+ 응용 프로그램을 유지 관리하기가 어렵고 이식성이 떨어짐). 스토리지가 적고 바이너리 (20)를 고수하는 것이 가장 느리다면 하드웨어에도 달려 있습니다. 그렇지 않으면 char (40)이라고 말할 것입니다. 사용하고있는 언어와 하드웨어로 몇 가지 테스트를 수행하지 않고 말하기가 어렵고 어떤 것이 가장 적합한 지 확인하십시오.
Francesco Casula

1
unhex (hash) = hash에서 단일 행을 가져 오기 위해 선택하는 것 이외의 작업을 수행하고 있다면 아마도 맞을 것입니다. 그러나 인덱스를 버퍼링하면이 방법으로 두 배의 메모리가 필요합니다.
nickdnk
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.