향상된 보안, 누락된 수정 사항, 기능 및 더 나은 .net 지원을 갖춘 bcrypt.codeplex.com 포팅.
nuget 또는 Paket을 사용하여 다운로드(https://fsprojects.github.io/Paket/)
패키지: https://www.nuget.org/packages/BCrypt.Net-Next/
서명된 패키지 - https://www.nuget.org/packages/BCrypt.Net-Next.StrongName/
테스트 하네스 폴더와 단위 테스트에는 다양한 예제가 있습니다.
가장 간단한 사용법은 다음과 같습니다.
비밀번호를 해시하려면:
파일 범위 네임스페이스가 표시됩니다. 필요한 경우 중괄호를 상상해 보세요.
Top level namespace
namespace DotNetSix ;
using BCrypt . Net ;
string passwordHash = BCrypt . HashPassword ( "my password" ) ;
네임스페이스가 using 문 뒤에 있는 경우 라이브러리 이름 지정으로 인해 .net이 이름 지정을 올바르게 확인하지 못하기 때문에 호출이 변경됩니다. 전체 네임스페이스를 입력하는 대신 간단히 아래와 같이 가져오기 별칭을 사용하는 것이 좋습니다.
using BC = BCrypt . Net . BCrypt ;
namespace DotNetSix ;
string passwordHash = BC . HashPassword ( "my password" ) ;
CSProj 수준에서 앨리어싱을 수행할 수도 있습니다. using 문을 전혀 추가할 필요가 없습니다.
이 예에서는 코드에서 BC.HashPassword() 별칭을 사용할 수 있습니다.
< ItemGroup >
<!-- emits global using BcryptNet = global::BCrypt.Net.BCrypt; -->
< Using Include = " BCrypt.Net.BCrypt " Alias = " BC " />
</ ItemGroup >
이 버전을 사용하면 다른 참조 없이 코드 베이스에서 Verify
및 HashPassword
호출할 수 있습니다.
< ItemGroup >
<!-- emits global using static global::BCrypt.Net.BCrypt; -->
< Using Include = " BCrypt.Net.BCrypt " Static = " True " />
</ ItemGroup >
참고: 이 라이브러리를 사용하면 사용자가 직접 솔트를 제공할 수 있지만 라이브러리에서 사용자를 위해 솔트를 생성하도록 허용하는 것이 좋습니다 . 이러한 메서드는 호환성을 유지하고 해당 메서드를 사용해야 할 수 있는 고급 크로스 플랫폼 요구 사항을 충족하기 위해 제공됩니다.
해시에 대해 비밀번호를 확인하려면 (해시를 저장하고 확인을 위해 저장소에서 검색했다고 가정):
네임스페이스에 대한 이전 참고 사항은 모두 여기에도 적용됩니다.
BCrypt . Verify ( "my password" , passwordHash ) ;
해싱에 대한 이 구현은 작업 요소(2^라운드 수)가 11로 설정된 솔트를 자동으로 생성합니다(대부분의 구현에서 기본값과 일치하며 현재 보안/위험 수준이 양호한 것으로 간주됨).
수학을 절약하기 위해 반복을 다루는 작은 테이블이 아래에 제공됩니다. 이 라이브러리에 허용되는 최소값은 호환성을 위해 4이고, 최대값은 31입니다(31이면 프로세서가 종료되기를 바랄 것입니다).
| Cost | Iterations |
|-------|--------------------------|
| 8 | 256 iterations |
| 9 | 512 iterations |
| 10 | 1,024 iterations |
| 11 | 2,048 iterations |
| 12 | 4,096 iterations |
| 13 | 8,192 iterations |
| 14 | 16,384 iterations |
| 15 | 32,768 iterations |
| 16 | 65,536 iterations |
| 17 | 131,072 iterations |
| 18 | 262,144 iterations |
| 19 | 524,288 iterations |
| 20 | 1,048,576 iterations |
| 21 | 2,097,152 iterations |
| 22 | 4,194,304 iterations |
| 23 | 8,388,608 iterations |
| 24 | 16,777,216 iterations |
| 25 | 33,554,432 iterations |
| 26 | 67,108,864 iterations |
| 27 | 134,217,728 iterations |
| 28 | 268,435,456 iterations |
| 29 | 536,870,912 iterations |
| 30 | 1,073,741,824 iterations |
| 31 | 2,147,483,648 iterations |
etc
콘솔 프로그램을 만들고 이 BCrypt 라이브러리를 추가하고 이 코드를 사용하여 실행할 수 있는 간단한 벤치마크입니다.
var cost = 16 ;
var timeTarget = 100 ; // Milliseconds
long timeTaken ;
do
{
var sw = Stopwatch . StartNew ( ) ;
BCrypt . HashPassword ( "RwiKnN>9xg3*C)1AZl.)y8f_:GCz,vt3T]PI" , workFactor : cost ) ;
sw . Stop ( ) ;
timeTaken = sw . ElapsedMilliseconds ;
cost -= 1 ;
} while ( ( timeTaken ) >= timeTarget ) ;
Console . WriteLine ( "Appropriate Cost Found: " + ( cost + 1 ) ) ;
Console . ReadLine ( ) ;
이는 65,536 iterations
인 16번에서 시작하여 시간 목표에 도달할 때까지 비용을 줄입니다. 허용되는 시간을 고려하는 것은 귀하에게 달려 있지만 10 미만인 경우 10으로 유지하고 더 큰 서버 패키지에 투자하는 것이 좋습니다.
bcrypt에 권장되는 56바이트 비밀번호 제한(널 종료 바이트 포함)은 Blowfish 키의 448비트 제한과 관련이 있습니다. 해당 제한을 초과하는 바이트는 해시에 완전히 혼합되지 않습니다. 따라서 bcrypt 비밀번호에 대한 72바이트 절대 제한은 해당 바이트가 결과 해시에 미치는 실제 영향을 고려할 때 관련성이 떨어집니다.
다른 언어에서는 사용된 엔트로피를 높이기 위해 암호/비밀번호를 미리 해싱하여 이 인식된 문제를 처리했으며, Dropbox는 이에 대한 더 많은 공개 기사 중 하나입니다.
다음 코드를 사용하여 간단히 향상된 해싱을 선택할 수 있습니다(기본적으로 메서드 호출 앞에 Enhanced를 붙임).
var enhancedHashPassword = BCrypt . EnhancedHashPassword ( myPassword ) ;
var validatePassword = BCrypt . EnhancedVerify ( myPassword , enhancedHashPassword ) ;
기본적으로 라이브러리는 암호 문구의 SHA384 해싱을 사용하며, 생성된 자료는 bcrypt로 전달되어 일반적인 bcrypt 루틴을 통해 해시를 형성합니다. 다른 버전의 SHA를 지정하거나 라이브러리의 주요 릴리스에서 변경되는 경우에 사용되는 버전을 코드에 명시적으로 설정하려는 경우 위의 다음 변경 사항을 사용하여 그렇게 할 수 있습니다.
var enhancedHashPassword = BCrypt . EnhancedHashPassword ( myPassword , hashType : HashType . SHA384 ) ;
var validatePassword = BCrypt . EnhancedVerify ( myPassword , enhancedHashPassword , hashType : HashType . SHA384 ) ;
왜 SHA384인가? 성능, 보안, 충돌 방지의 균형이 잘 잡혀 있으며 길이 확장 공격에 취약하지 않은 유일한 버전입니다 https://blog.skullsecurity.org/2012/everything-you-need-to-know-about-hash -길이 확장 공격 .
향상된 엔트로피를 사용해야 합니까? 사용해도 손해 볼 것은 없다
SHA 유형을 변경해야 하는 이유는 무엇입니까? SHA256을 사용하는 PassLib 해시와 같은 일부 라이브러리는 대부분 호환성 문제입니다. DropBox는 SHA512를 사용했기 때문에 Dropbox에서 일했다면 호환성을 원할 것입니다. 향상은 이미 미리 해시하고 표준 메서드 호출에 전달할 수 있다는 점에서 대부분 편리한 확장입니다.
그것은 무엇을 합니까? inputBytes SHA 해시로 비밀번호의 utf8 바이트를 가져와서(다른 언어 구현과의 호환성을 위해) base64로 변환한 다음 해당 바이트를 사용하여 표준 bcrypt 호출을 수행합니다.
현재 SDK https://www.microsoft.com/net/download에는 최소한 VS2022가 필요합니다.
너겟 패키지는 buildfornuget.cmd
실행하여 빌드할 수 있습니다.
dotnet restore . s rc
dotnet pack . s rc B Crypt.Net --configuration Release
dotnet test .srcBCrypt.Net.UnitTests
TestGenerateSaltWithMaxWorkFactor
실행하려면 상당한 시간이 걸립니다.
C#으로 구현된 jBCrypt의 .Net 포트입니다. 이는 Blowfish 암호화 알고리즘의 키잉 일정 변형을 사용하고 해시 함수의 비용을 결정할 수 있는 작업 요소를 도입하여 알고리즘이 "미래 보장형"이 되도록 합니다.
이것은 모든 의도와 목적을 위해 Damien Miller가 작성한 jBCrypt의 직접 포트입니다. 주요 차이점은 몇 가지 편의 메서드를 추가하고 약간의 리팩토링을 수행한다는 것입니다. BCrypt.Net과 jBCrypt의 패리티를 확인하는 가장 쉬운 방법은 단위 테스트를 비교하는 것입니다.
BCrypt가 중요한 이유에 대한 개요는 암호를 안전하게 저장하는 방법을 참조하세요. 일반적으로 해시를 생성하는 데 더 많은 CPU 성능이 필요하도록 시간이 지남에 따라 조정될 수 있는 해싱 알고리즘입니다. 이는 본질적으로 무어의 법칙에 대한 어느 정도 보호를 제공합니다. 즉, 컴퓨터가 빨라질수록 이 알고리즘은 더 많은 CPU 성능을 요구하도록 조정될 수 있습니다. 특정 비밀번호를 해시하는 데 필요한 CPU 성능이 높을수록 "해커"가 비밀번호당 투자해야 하는 시간이 늘어납니다. 결과 해시에 "작업 요소"가 포함되어 있으므로 이 알고리즘에 의해 생성된 해시는 순방향/역방향 호환이 가능합니다.
이는 Blowfish 암호화 알고리즘의 키잉 일정 변형을 사용하고 해시 함수의 비용을 결정할 수 있는 작업 요소를 도입합니다. 이 때문에 BCrypt는 무어의 법칙을 따라갈 수 있습니다. 컴퓨터가 빨라질수록 작업 요소가 증가하고 해시가 느려집니다.
Niels Provos와 David Mazières는 Blowfish를 기반으로 bcrypt라는 crypt() 체계를 설계하고 1999년 USENIX에서 발표했습니다.[14]
이 해시의 인쇄 가능한 형식은 다음으로 시작합니다.
$2$ – Currently obsolete
$2a$ – The current key used to identify this scheme.
Since a major security flaw was discovered in 2011 in a third-party implementation of the algorithm,
hashes indicated by this string are now ambiguous and might have been generated by the flawed
implementation, or a subsequent fixed, implementation.
The flaw may be triggered by some password strings containing non-ASCII characters, such as specially
crafted password strings.
$2b$ – Used by some recent implementations which include a mitigation to a wraparound problem.
Previous versions of the algorithm have a problem with long passwords. By design, long passwords
are truncated at 72 characters, but there is an 8-bit wraparound problem with certain password
lengths resulting in weak hashes.
$2x$ – Post-2011 bug discovery, old hashes can be renamed to be $2x$ to indicate that they were generated with
the broken algorithm. These hashes are still weak, but at least it's clear which algorithm was used to
generate them.
$2y$ – Post Post-2011 bug discovery, $2y$ may be used to unambiguously use the new, corrected algorithm. On an
implementation suffering from the bug, $2y$ simply won't work. On a newer, fixed implementation, it will
produce the same result as using $2a$.
무엇보다도 이 라이브러리는 mindrot
의 jBCrypt 포트에서 시작되었으며 이후 bcrypt 개정이 일치하도록 설정되었습니다(이 경우 $2a$
. 단일 개정만 처리하면 마이그레이션 및 기타 문제를 처리하기 위해 개정을 변경한 구현으로 인해 플랫폼 간 문제가 발생하므로 이는 변경되었습니다.
The original bcrypt code (released in OpenBSD 2.1) identified itself as
$2$. Shortly after release, a bug was fixed and the hash identifier
changed to $2a$. Support for "minor" versions wasn't really
planned, but it was backwards compatible.
Solar Designer wrote a second implementation of bcrypt. This
reimplementation suffered from a flaw dealing with 8 bit characters
and led to the introduction of the 'x' and 'y' flavours. OpenBSD did
not have this problem and supports neither 'x' nor 'y' hash versions.
---
Solar found a bug in their OpenBSD implementation of bcrypt when hashing
long passwords. The length is stored in an unsigned char type, which
will overflow and wrap at 256. Although we consider the existence of
affected hashes very rare, in order to differentiate hashes generated
before and after the fix, we are introducing a new minor 'b'.
OpenBSD 5.5 (coming this spring) will accept and verify 'b' hashes,
although it will still generate 'a' hashes. OpenBSD 5.6 (coming this
fall) will change to generating 'b' hashes by default.
A future release of Solar's bcrypt code should also support 'b'.
2a, 2x, 2y, 2b 사이에는 차이가 없습니다. 모두 동일한 결과를 출력합니다.
릴리스 노트는 여기에 있습니다 https://github.com/BcryptNet/bcrypt.net/releases
v4.0.3 - .net 6 타겟팅 추가 목표물을 정리하세요.
v4.0.2 - .net 5 타겟팅 추가 릴리스를 사용하여 shaxxx
생성을 래핑합니다.
v4.0.0(주요 변경 사항) - 생성된 해시가 다른 언어 간에 작동하지 않게 만드는 Enhanced Hashing
의 버그가 발견되었습니다. V4는 이에 대한 수정 사항을 제공할 뿐만 아니라 PHP 및 Python의 테스트 벡터를 추가하여 문제가 앞으로도 계속 수정되도록 합니다. V4는 또한 Base64가 추가되기 전에 제공된 레거시 384 옵션을 제거합니다.
v3.5.0 - 생성된 해시가 서로 다른 언어 간에 작동하지 않게 만드는 Enhanced Hashing
의 버그가 발견되었습니다. 수정 사항 3.5 릴리스에는 Verify
기능이 포함되어 있으며 HashPassword
추가 v4CompatibleEnhancedEntropy
매개 변수가 제공되었습니다. 이를 통해 사용자는 강화된 해시를 정상적으로 확인할 수 있습니다. 그런 다음 V4를 사용하여 다시 해시하고 저장합니다. 이 기능은 순전히 마이그레이션을 허용하기 위한 것이며 V4에서는 제거되었습니다.
v3.3.3 -netcore를 위한 성능(힙 감소) 및 정규 표현식 제거 https://github.com/BcryptNet/bcrypt.net/releases/tag/3.3.0
v2.1.3 -
v2.1.2 -
PasswordNeedsReshash
의 오타를 PasswordNeedsRehash
로 수정하세요.v2.1.1 -
v2.1.0 -
PasswordNeedsReshash(string hash, int newMinimumWorkLoad)
추가했습니다.ValidateAndReplacePassword
메서드를 추가하세요. 인증 실패 시 BcryptAuthenticationException
발생합니다.v2.0.1 -
v2.0.0 -
타이밍 공격으로 인한 위험을 줄이기 위해 안전 동등 항목을 포함하고 대부분의 .net용으로 패키지된 최신 릴리스 https://en.wikipedia.org/wiki/Timing_attack / https://cryptocoding.net/index.php/Coding_rules#Compare_secret_strings_in_constant_time 기술적으로 BCrypt의 구현 세부 사항은 이론적으로 타이밍 공격을 완화합니다. 그러나 Bcrypt.net 공식 유효성 검사 기능은 해시 비교에서 일치하지 않는 바이트가 발견되는 즉시 반환되므로 타이밍 공격에 취약했습니다.