[hash] 일반적으로 신뢰할 수있는 것으로 간주되는 SHA-256 자바 스크립트 구현이 있습니까?

포럼에 대한 로그인을 작성 중이며 서버로 보내기 전에 비밀번호 클라이언트 측을 자바 스크립트로 해시해야합니다. 실제로 신뢰할 수있는 SHA-256 구현을 파악하는 데 문제가 있습니다. 모든 사람이 사용하는 권위있는 스크립트가있을 것으로 예상했지만 모두 자체 구현을 가진 다양한 프로젝트를 찾고 있습니다.

다른 사람의 암호 화폐를 사용하는 것은 여러분이 직접 검토 할 자격이없는 한 항상 믿음의 도약이며 “신뢰할 수있는”에 대한 보편적 인 정의가 없다는 것을 알고 있습니다. 무엇을 사용해야하는지에 대한 합의. 그냥 순진한가요?

댓글에 많이 나오기 때문에 편집 : 예, 서버 측에서 다시 더 엄격한 해시를 수행합니다. 클라이언트 측 해싱은 데이터베이스에 저장하는 최종 결과가 아닙니다. 클라이언트 측 해싱은 인간 클라이언트가 요청하기 때문입니다. 그들은 특별한 이유를 제시하지 않았으며 아마도 그들은 과잉 살인을 좋아할 것입니다.



답변

스탠포드 JS 암호화 라이브러리는 SHA-256의 구현을 포함한다. JS의 암호화는 다른 구현 플랫폼만큼 잘 검증되지는 않았지만, 이것은 암호화 분야에서 잘 확립되고 신뢰할 수있는 이름 인 Dan Boneh 가 적어도 부분적으로 개발하고 어느 정도 후원합니다. , 그리고 프로젝트가 자신이하고있는 일을 실제로 아는 누군가에 의해 약간의 감독이 있음을 의미합니다. 이 프로젝트는 NSF 에서도 지원합니다 .

그러나 …
… 제출하기 전에 클라이언트 측에서 암호를 해시하면 해시는 암호가되고 원래 암호는 무의미 해집니다. 공격자는 사용자를 가장하기 위해 해시를 가로 채기 만하면됩니다. 해시가 수정되지 않은 상태로 서버에 저장되면 서버는 일반 텍스트로 실제 암호 (해시)를 저장 합니다. .

따라서 이전에 신뢰할 수 있었던 계획에 자체 개선 사항추가하기 로 결정했기 때문에 이제 보안이 더 나빠 졌습니다.


답변

https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest 나는 내부의 js 모듈을 사용하여이 조각을 발견 :

async function sha256(message) {
    // encode as UTF-8
    const msgBuffer = new TextEncoder().encode(message);

    // hash the message
    const hashBuffer = await crypto.subtle.digest('SHA-256', msgBuffer);

    // convert ArrayBuffer to Array
    const hashArray = Array.from(new Uint8Array(hashBuffer));

    // convert bytes to hex string                  
    const hashHex = hashArray.map(b => ('00' + b.toString(16)).slice(-2)).join('');
    return hashHex;
}

참고는 crypto.subtle에서만 사용할 수에서와 httpslocalhost-와 지역 개발을위한 예를 들어 python3 -m http.server당신은 당신이 라인을 추가해야합니다 /etc/hosts:
0.0.0.0 localhost

재부팅-당신은 localhost:8000작업으로 열 수 있습니다 crypto.subtle.


답변

단조 공장 의 SHA-256 구현은 빠르고 안정적입니다.

여러 SHA-256 JavaScript 구현에 대한 테스트를 실행하려면 다음으로 이동하십시오. http://brillout.github.io/test-javascript-hash-implementations/ .

내 컴퓨터의 결과는 forge가 가장 빠른 구현이며 수락 된 답변에 언급 된 Stanford Javascript Crypto Library (sjcl)보다 훨씬 빠르다는 것을 나타냅니다.

Forge는 크기가 256KB이지만 SHA-256 관련 코드를 추출하면 크기가 4.5KB로 줄어 듭니다. https://github.com/brillout/forge-sha256 참조


답변

관심있는 사람들을 위해 다음을 사용하여 SHA-256 해시를 만드는 코드입니다 sjcl.

import sjcl from 'sjcl'

const myString = 'Hello'
const myBitArray = sjcl.hash.sha256.hash(myString)
const myHash = sjcl.codec.hex.fromBits(myBitArray)


답변

아니요, 브라우저 JavaScript를 사용하여 암호 보안을 향상시킬 수있는 방법은 없습니다. 이 기사 를 읽어 보는 것이 좋습니다 . 귀하의 경우 가장 큰 문제는 닭 계란 문제입니다.

Javascript 암호화를 제공하는 데있어 “닭 달걀 문제”는 무엇입니까?

네트워크가 암호를 전달하는 것을 신뢰하지 않거나, 더 나쁜 것은 서버가 사용자 비밀을 유지하지 않는다는 것을 신뢰하지 않는 경우, 보안 코드를 제공하는 것을 신뢰할 수 없습니다. 암호를 도입하기 전에 암호를 스니핑하거나 일기를 읽던 공격자는 단순히 암호 코드를 하이재킹하는 것입니다.

[…]

TLS / SSL을 사용하여 Javascript 암호화 코드를 전달할 수없는 이유는 무엇입니까?

할 수 있습니다. 생각보다 어렵지만 SSL을 사용하여 Javascript 암호화를 브라우저에 안전하게 전송합니다. 문제는 SSL로 보안 채널을 설정 했으므로 더 이상 Javascript 암호화가 필요하지 않다는 것입니다. 당신은 “진짜”암호화를 가지고 있습니다.

이로 인해 :

Javascript에서 암호화 코드를 실행할 때의 문제는 암호화가 의존하는 거의 모든 기능이 호스팅 페이지를 구축하는 데 사용되는 콘텐츠에 의해 자동으로 무시 될 수 있다는 것입니다. 암호화 보안은 프로세스 초기에 (가짜 난수를 생성하거나 알고리즘에서 사용하는 상수 및 매개 변수를 조작하여) 또는 나중에 (키 자료를 공격자에게 다시 스 피팅하여) 취소 할 수 있습니다. 가능성이 가장 높은 시나리오에서 — 암호 화폐를 완전히 우회함으로써.

어떤 자바 스크립트 코드도 실행 환경을 확인할 수있는 신뢰할 수있는 방법이 없습니다. 자바 스크립트 암호화 코드는 “난 정말 난수 생성기를 다루고 있습니까, 아니면 공격자가 제공 한 일부 팩시밀리를 다루고 있습니까?”라고 묻지 않습니다. 그리고 그것은 “저자 인 내가 승인하는 방식을 제외하고는 아무도이 암호 비밀로 아무것도 할 수 없다”고 주장 할 수 없습니다. 이들은 암호화를 사용하는 다른 환경에서 종종 제공되는 두 가지 속성이며 Javascript에서는 불가능합니다.

기본적으로 문제는 다음과 같습니다.

  • 클라이언트는 서버를 신뢰하지 않으므로 추가 보안 코드를 추가하려고합니다.
  • 해당 보안 코드는 서버 (신뢰하지 않는 서버)에서 제공합니다.

또는

  • 클라이언트는 SSL을 신뢰하지 않으므로 추가 보안 코드를 사용하기를 원합니다.
  • 해당 보안 코드는 SSL을 통해 전달됩니다.

참고 : 또한 SHA-256은 무염 비 반복 암호무차별 대입 하기가 쉽기 때문에 이에 적합하지 않습니다 . 어쨌든 이것을하기로 결정 했다면 , bcrypt , scrypt 또는 PBKDF2 의 구현을 찾으십시오 .


답변

이 구현은 사용하기 매우 쉽습니다. 또한 넉넉한 BSD 스타일 라이센스가 있습니다.

jsSHA : https://github.com/Caligatio/jsSHA

SHA-256 해시의 16 진수 문자열 표현을 가져 오는 빠른 방법이 필요했습니다. 3 줄만 필요했습니다.

var sha256 = new jsSHA('SHA-256', 'TEXT');
sha256.update(some_string_variable_to_hash);
var hash = sha256.getHash("HEX");


답변

tylerl이 언급 한 Stanford lib 외에. jsrsasign이 매우 유용하다는 것을 알았 습니다 (Github repo : https://github.com/kjur/jsrsasign ). 정확히 얼마나 신뢰할 수 있는지는 모르지만 SHA256, Base64, RSA, x509 등의 API를 사용했으며 꽤 잘 작동합니다. 실제로 Stanford lib도 포함됩니다.

원하는 것이 SHA256 뿐이라면 jsrsasign 은 과잉 일 수 있습니다. 하지만 관련 분야에서 다른 요구 사항이 있으면 잘 맞는 것 같습니다.