HS* JWT 알고리즘) 예제RS* , PS* , ES* 및 EdDSA 알고리즘) 예제boring 상자의 편집 문제를 해결합니다일반적인 JWT 보안 함정을 피하면서 단순성에 중점을 둔 Rust에 대한 새로운 JWT (JSON Web Tokens) 구현.
jwt-simple 무시되지 않으며 일반적으로 배포되는 모든 인증 및 서명 알고리즘을 지원합니다.
| JWT 알고리즘 이름 | 설명 |
|---|---|
HS256 | HMAC-SHA-256 |
HS384 | HMAC-SHA-384 |
HS512 | HMAC-SHA-512 |
BLAKE2B | Blake2b-256 |
RS256 | PKCS#1V1.5 패딩 / SHA-256이있는 RSA |
RS384 | PKCS#1V1.5 패딩 / SHA-384가있는 RSA |
RS512 | PKCS#1V1.5 패딩 / SHA-512가있는 RSA |
PS256 | PSS 패딩 / SHA-256이있는 RSA |
PS384 | PSS 패딩 / SHA-384가있는 RSA |
PS512 | PSS 패딩 / SHA-512가있는 RSA |
ES256 | P256 / SHA-256에 대한 ECDSA |
ES384 | P384 / SHA-384에 대한 ECDSA |
ES256K | SECP256K1 / SHA-256에 대한 ECDSA |
EdDSA | ED25519 |
jwt-simple Box에서 WebAssembly/Wasi로 컴파일 될 수 있습니다. 빠르게 컴퓨팅 서비스와 완전히 호환됩니다.
중요 : JWT의 목적은 비밀 키를 아는 당사자가 데이터를 생성했는지 확인하는 것입니다. JWT 데이터는 단순히 Base64로 인코딩되며 암호화되지 않습니다.
cargo.toml :
[ dependencies ]
jwt-simple = " 0.12 "녹:
use jwt_simple :: prelude :: * ; 오류는 jwt_simple::Error 값으로 반환됩니다 ( thiserror 상자의 Error 유형에 대한 별칭).
HS* JWT 알고리즘) 예제인증 체계는 토큰을 생성하고 검증하기 위해 동일한 키를 사용합니다. 다시 말해, 양 당사자는 궁극적으로 서로를 신뢰해야합니다. 그렇지 않으면 검증자는 임의의 토큰을 만들 수 있습니다.
주요 창출 :
use jwt_simple :: prelude :: * ;
// create a new key for the `HS256` JWT algorithm
let key = HS256Key :: generate ( ) ; 키는 key.to_bytes() 의 바이트로 내보낼 수 있고 HS256Key::from_bytes() 로 복원 할 수 있습니다.
토큰 생성 :
/// create claims valid for 2 hours
let claims = Claims :: create ( Duration :: from_hours ( 2 ) ) ;
let token = key . authenticate ( claims ) ? ;-> 완료!
let claims = key . verify_token :: < NoCustomClaims > ( & token , None ) ? ;-> 완료! 추가 단계가 필요하지 않습니다.
주요 만료, 시작 시간, 인증 태그 등이 자동으로 확인됩니다. 인증 태그가 주어진 키에 대해 유효하지 않은 경우 함수가 JWTError::InvalidAuthenticationTag 에서 실패합니다.
필요한 경우 전체 청구 세트는 claims 객체에서 검사 할 수 있습니다. NoCustomClaims 응용 프로그램에서 표준 청구 세트 만 사용하지만 응용 프로그램 정의 청구도 지원할 수 있음을 의미합니다.
추가 확인 단계는 ValidationOptions 구조를 통해 선택적으로 활성화 될 수 있습니다.
let mut options = VerificationOptions :: default ( ) ;
// Accept tokens that will only be valid in the future
options . accept_future = true ;
// Accept tokens even if they have expired up to 15 minutes after the deadline,
// and/or they will be valid within 15 minutes.
// Note that 15 minutes is the default, since it is very common for clocks to be slightly off.
options . time_tolerance = Some ( Duration :: from_mins ( 15 ) ) ;
// Reject tokens if they were issued more than 1 hour ago
options . max_validity = Some ( Duration :: from_hours ( 1 ) ) ;
// Reject tokens if they don't include an issuer from that set
options . allowed_issuers = Some ( HashSet :: from_strings ( & [ "example app" ] ) ) ;
// see the documentation for the full list of available options
let claims = key . verify_token :: < NoCustomClaims > ( & token , Some ( options ) ) ? ; allowed_issuers 및 allowed_audiences 는 문자열이 아니라 문자열 세트 (Rust 표준 라이브러리의 HashSet 유형 사용) 세트입니다. 응용 프로그램은 여러 반환 값을 허용 할 수 있습니다.
RS* , PS* , ES* 및 EdDSA 알고리즘) 예제시그니처에는 키 쌍이 필요합니다. 토큰을 만드는 데 사용되는 비밀 키와 공개 키는 확인할 수 있습니다.
고객과 API 제공 업체간에 교환 된 토큰과 같이 두 당사자가 궁극적으로 서로를 신뢰하지 않으면 항상 서명 체계를 사용하십시오.
주요 창출 :
use jwt_simple :: prelude :: * ;
// create a new key pair for the `ES256` JWT algorithm
let key_pair = ES256KeyPair :: generate ( ) ;
// a public key can be extracted from a key pair:
let public_key = key_pair . public_key ( ) ; use jwt_simple :: prelude :: * ;
// create a new key pair for the `ES384` JWT algorithm
let key_pair = ES384KeyPair :: generate ( ) ;
// a public key can be extracted from a key pair:
let public_key = key_pair . public_key ( ) ;키는 나중에 재사용을 위해 바이트로 내보내고 개별 매개 변수, der- 인코딩 된 데이터 또는 PEM 인코딩 된 데이터에서 바이트 또는 RSA에서 가져올 수 있습니다.
OpenSSL 및 PEM 수입을 사용하여 RSA 키 페어 생성 : 비밀 키 :
openssl genrsa -out private.pem 2048
openssl rsa -in private.pem -outform PEM -pubout -out public.pem let key_pair = RS384KeyPair :: from_pem ( private_pem_file_content ) ? ;
let public_key = RS384PublicKey :: from_pem ( public_pem_file_content ) ? ; 토큰 생성 및 검증은 HS* 알고리즘과 동일한 방식으로 작동합니다. 토큰은 키 쌍으로 생성되고 해당 공개 키를 사용하여 확인됩니다.
토큰 생성 :
/// create claims valid for 2 hours
let claims = Claims :: create ( Duration :: from_hours ( 2 ) ) ;
let token = key_pair . sign ( claims ) ? ;토큰 검증 :
let claims = public_key . verify_token :: < NoCustomClaims > ( & token , None ) ? ;사용 가능한 검증 옵션은 대칭 알고리즘과 함께 사용되는 것과 동일합니다.
클레임 객체는 기본적으로 모든 표준 클레임을 지원하며 편리한 도우미를 통해 직접 또는 직접 설정할 수 있습니다.
let claims = Claims :: create ( Duration :: from_hours ( 2 ) ) .
with_issuer ( "Example issuer" ) . with_subject ( "Example subject" ) ; 그러나 응용 프로그램 정의 청구도 정의 할 수 있습니다. 이것들은 단순히 직렬화 가능한 유형으로 존재해야합니다 ( serde 상자가 필요합니다).
# [ derive ( Serialize , Deserialize ) ]
struct MyAdditionalData {
user_is_admin : bool ,
user_country : String ,
}
let my_additional_data = MyAdditionalData {
user_is_admin : false ,
user_country : "FR" . to_string ( ) ,
} ;사용자 정의 데이터로 청구 생성 :
let claims = Claims :: with_custom_claims ( my_additional_data , Duration :: from_secs ( 30 ) ) ;사용자 정의 데이터로 검증을 청구합니다. 사용자 정의 데이터 유형의 존재에 유의하십시오.
let claims = public_key . verify_token :: < MyAdditionalData > ( & token , None ) ? ;
let user_is_admin = claims . custom . user_is_admin ;키 식별자와 같은 속성은 세트에서 올바른 키를 선택하기 위해 태그 또는 서명 검증 전에 유용 할 수 있습니다.
let metadata = Token :: decode_metadata ( & token ) ? ;
let key_id = metadata . key_id ( ) ;
let algorithm = metadata . algorithm ( ) ;
// all other standard properties are also accessible중요 : 키 ID 나 알고리즘을 신뢰할 수 없습니다. 이것은 JWT 표준의 불완전한 설계 결함입니다.
결과적으로 algorithm 디버깅 목적으로 만 사용해야하며 키 유형을 선택하지 않아야합니다. 마찬가지로 key_id 동일한 알고리즘을 위해 만든 키 세트에서 키를 선택하는 데만 사용해야합니다.
최소한의 경우 서명 체계가 원래 토큰을 만드는 데 사용 된 경우 HS* 사용한 검증을 금지해야합니다.
키 식별자는 검증을 위해 어떤 공개 키 (또는 공유 키)를 검증하는 데 사용해야하는 것을 확인합니다. 기존 공유 키, 키 쌍 및 공개 키에 언제든지 첨부 할 수 있습니다.
let public_key_with_id = public_key . with_key_id ( & "unique key identifier" ) ; 이를 응용 프로그램에 위임하는 대신 jwt-simple 기존 키에 대한 이러한 식별자를 생성 할 수 있습니다.
let key_id = public_key . create_key_id ( ) ;이렇게하면 키에 대한 텍스트 인코딩 식별자를 생성하고 첨부하여 반환합니다.
식별자가 공유 키 또는 키 쌍에 첨부 된 경우 그들과 함께 생성 된 토큰에 포함됩니다.
jwt-simple 에는 재생 공격을 완화하는 메커니즘이 포함되어 있습니다.
create_nonce() 클레임 함수를 사용하여 Nonce를 생성하고 새 토큰에 첨부 할 수 있습니다. 검증 절차는 나중에 예상되는 Nonce ( required_nonce 확인 옵션)가 포함되지 않는 토큰을 거부 할 수 있습니다. 개발 코드에는 CWT 토큰의 실험적인 구문 분석 및 검증을 가능하게하는 cwt 화물 기능이 포함되어 있습니다.
CWT는 맞춤 주장을 지원하지 않습니다. 필요한 식별자는 아직 표준화되지 않았습니다.
또한 JSON 및 CBOR 사막화를위한 기존 Rust Crates는 안전하지 않습니다. 신뢰할 수없는 당사자는 많은 메모리와 CPU가 필요한 직렬화 된 객체를 보낼 수 있습니다. JSON에 반창고가 추가되었지만 현재 Rust 툴링을 사용하면 CBOR에 대해 까다로울 수 있습니다.
완화로서, 우리는 응용 프로그램의 맥락에서 너무 큰 토큰을 거부하는 것이 좋습니다. 이는 max_token_length verification 옵션으로 수행 할 수 있습니다.
boring 상자의 편집 문제를 해결합니다 의존성 중 하나 ( boring 상자) 중 하나의 휴대 성 문제에 대한 임시 해결 방법 으로이 라이브러리는 녹 구현 만 사용하도록 컴파일 할 수 있습니다.
그렇게하려면화물 구성에서 default-features=false, features=["pure-rust"] 로 상자를 가져 오십시오.
무조건하지 마십시오. 이것은 매우 구체적인 설정 및 대상에만 필요하며 boring 상자와 관련된 문제가 해결 될 때까지만 필요합니다. 화물에서이를 구성하는 방법도 향후 버전에서 변경 될 수 있습니다.
musl Library를 대상으로 한 정적 빌드는 해당 해결 방법을 요구하지 않습니다. cargo-zigbuild 사용하여 프로젝트를 구축하십시오.
wasm32-freestanding 대상 (때로는 ROST의 wasm32-unknown-unknown 이라고도 함)이 지원됩니다 ( "IT Compiles"에서와 같이).
그러나 기본 JavaScript 구현을 사용하는 것이 대신 적극 권장됩니다. JavaScript에는 WebCrypto API를 활용하여 WebAssembly 모듈보다 더 나은 성능 및 보안 보증을 제공하는 고품질 JWT 구현이 있습니다.
이 상자는 JWT의 승인이 아닙니다. JWT는 끔찍한 디자인이며 "이것은 표준이지만"라는 많은 예 중 하나가 반드시 그것이 좋은 것을 의미하지는 않습니다.
토큰 생성과 검증을 모두 제어하는 경우 대신 Paseto 또는 Biscuit을 강력히 추천합니다.
그러나 JWT는 여전히 업계에서 널리 사용되며 인기있는 API와 의사 소통하는 데 절대적으로 필수적입니다.
이 상자는 다음과 같이 설계되었습니다.
None Signature 방법을 제외하고) 제공하십시오.