DataFlex
DataFlex
Validate JWS with Multiple Signatures using the General JSON Serialization Format
See more JSON Web Signatures (JWS) Examples
Validates and recovers data and headers from a JSON Web Signature (JWS) containing 3 signatures.Note: Chilkat supports all of the following JWS algorithms:
+--------------+-------------------------------+--------------------+ | "alg" Param | Digital Signature or MAC | Implementation | | Value | Algorithm | Requirements | +--------------+-------------------------------+--------------------+ | HS256 | HMAC using SHA-256 | Required | | HS384 | HMAC using SHA-384 | Optional | | HS512 | HMAC using SHA-512 | Optional | | RS256 | RSASSA-PKCS1-v1_5 using | Recommended | | | SHA-256 | | | RS384 | RSASSA-PKCS1-v1_5 using | Optional | | | SHA-384 | | | RS512 | RSASSA-PKCS1-v1_5 using | Optional | | | SHA-512 | | | ES256 | ECDSA using P-256 and SHA-256 | Recommended+ | | ES384 | ECDSA using P-384 and SHA-384 | Optional | | ES512 | ECDSA using P-521 and SHA-512 | Optional | | PS256 | RSASSA-PSS using SHA-256 and | Optional | | | MGF1 with SHA-256 | | | PS384 | RSASSA-PSS using SHA-384 and | Optional | | | MGF1 with SHA-384 | | | PS512 | RSASSA-PSS using SHA-512 and | Optional | | | MGF1 with SHA-512 | | +--------------+-------------------------------+--------------------+
Chilkat DataFlex Downloads
Use ChilkatAx-win32.pkg
Procedure Test
Boolean iSuccess
Handle hoSbRsaJwk
Variant vRsaKey
Handle hoRsaKey
Handle hoSbEccJwk
Variant vEccKey
Handle hoEccKey
String sHmacKey
Variant vSbJws
Handle hoSbJws
Handle hoJws
Handle hoSbKeyId
Boolean iBCaseSensitive
Variant vProtHeader
Handle hoProtHeader
Integer iNumSignatures
Integer i
Integer v
String sTemp1
Boolean bTemp1
Move False To iSuccess
// This requires the Chilkat API to have been previously unlocked.
// See Global Unlock Sample for sample code.
// First, prepare the public keys that will be needed for each signature.
// ---------------------------------------------------
// Use the following RSA key loaded from JWK format.
Get Create (RefClass(cComChilkatStringBuilder)) To hoSbRsaJwk
If (Not(IsComObjectCreated(hoSbRsaJwk))) Begin
Send CreateComObject of hoSbRsaJwk
End
Get ComAppend Of hoSbRsaJwk '{"kty":"RSA",' To iSuccess
Get ComAppend Of hoSbRsaJwk '"n":"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddx' To iSuccess
Get ComAppend Of hoSbRsaJwk "HmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMs" To iSuccess
Get ComAppend Of hoSbRsaJwk "D1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSH" To iSuccess
Get ComAppend Of hoSbRsaJwk "SXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdV" To iSuccess
Get ComAppend Of hoSbRsaJwk "MTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8" To iSuccess
Get ComAppend Of hoSbRsaJwk 'NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ",' To iSuccess
Get ComAppend Of hoSbRsaJwk '"e":"AQAB"' To iSuccess
Get ComAppend Of hoSbRsaJwk "}" To iSuccess
Get Create (RefClass(cComChilkatPublicKey)) To hoRsaKey
If (Not(IsComObjectCreated(hoRsaKey))) Begin
Send CreateComObject of hoRsaKey
End
Get ComGetAsString Of hoSbRsaJwk To sTemp1
Get ComLoadFromString Of hoRsaKey sTemp1 To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoRsaKey To sTemp1
Showln sTemp1
Procedure_Return
End
// ---------------------------------------------------
// Use the following ECC public key loaded from JWK format.
Get Create (RefClass(cComChilkatStringBuilder)) To hoSbEccJwk
If (Not(IsComObjectCreated(hoSbEccJwk))) Begin
Send CreateComObject of hoSbEccJwk
End
Get ComAppend Of hoSbEccJwk '{"kty":"EC",' To iSuccess
Get ComAppend Of hoSbEccJwk '"crv":"P-256",' To iSuccess
Get ComAppend Of hoSbEccJwk '"x":"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU",' To iSuccess
Get ComAppend Of hoSbEccJwk '"y":"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0"' To iSuccess
Get ComAppend Of hoSbEccJwk "}" To iSuccess
Get Create (RefClass(cComChilkatPublicKey)) To hoEccKey
If (Not(IsComObjectCreated(hoEccKey))) Begin
Send CreateComObject of hoEccKey
End
Get ComGetAsString Of hoSbEccJwk To sTemp1
Get ComLoadFromString Of hoEccKey sTemp1 To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoEccKey To sTemp1
Showln sTemp1
Procedure_Return
End
// ---------------------------------------------------
// The HMAC key (in base64url format)
Move "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow" To sHmacKey
// The code below will verify each of the signatures in this JWS:
// {
// "payload": "SW4gb3VyIHZpbGxhZ2UsIGZvbGtzIHNheSBHb2QgY3J1bWJsZXMgdXAgdGhlIG9sZCBtb29uIGludG8gc3RhcnMu",
// "signatures": [
// {
// "protected": "eyJhbGciOiJSUzI1NiIsImtpZCI6Im15UnNhS2V5In0",
// "signature": "IPMQ02niTQDwLzsRZSCaEm9VEyAX_AVe3HWjniNt9kW-a8d6ZVbd2k6jGae8s1yIh0cgxDnXQ6-p6_sBI0cnMO0xpuJANhh2vFtNJl5lisad94-H3mB3lSfafRqxeYp5D8bh39BPv7y3PrUNVMQdKEJp_D5oJ0ROPTIYx3EG8eJQOx1HO0KqhcUo401XR6KSsIyFm5joBLNKTVzxZUTT1RRZZtwTdeZkbGevugIOX_9gHAtARpV6WaFA4Vvjnq8X9wPgqjWNCQRupadhTPz0JAsa-wy5vXQjsFlXAn43mDPpMfna5Ab3F5pS4yDwkbX6nRn7XBxH1SnnNJRFholQZw"
// },
// {
// "protected": "eyJhbGciOiJFUzI1NiIsImtpZCI6Im15RWNLZXkifQ",
// "signature": "1OQtaT3pgZmkDxvlfghvxL_8kX16WIen6u1MadEq1pA4qytA0--_EwZDNk00GDPWFpoJtKznibMZzLOg_UhHIw"
// },
// {
// "protected": "eyJhbGciOiJIUzI1NiIsImtpZCI6Im15TWFjS2V5In0",
// "signature": "YY8yVjmJJfy7YJOn3uUydG8WCY2PEuCvOLil5Ks5lnw"
// }
// ]
// }
Get Create (RefClass(cComChilkatStringBuilder)) To hoSbJws
If (Not(IsComObjectCreated(hoSbJws))) Begin
Send CreateComObject of hoSbJws
End
Get ComAppend Of hoSbJws "{ " To iSuccess
Get ComAppend Of hoSbJws ' "payload": "SW4gb3VyIHZpbGxhZ2UsIGZvbGtzIHNheSBHb2QgY3J1bWJsZXMgdXAgdGhlIG9sZCBtb29uIGludG8gc3RhcnMu",' To iSuccess
Get ComAppend Of hoSbJws ' "signatures": [' To iSuccess
Get ComAppend Of hoSbJws " { " To iSuccess
Get ComAppend Of hoSbJws ' "protected": "eyJhbGciOiJSUzI1NiIsImtpZCI6Im15UnNhS2V5In0",' To iSuccess
Get ComAppend Of hoSbJws ' "signature": "IPMQ02niTQDwLzsRZSCaEm9VEyAX_AVe3HWjniNt9kW-a8d6ZVbd2k6jGae8s1yIh0cgxDnXQ6-p6_sBI0cnMO0xpuJANhh2vFtNJl5lisad94-H3mB3lSfafRqxeYp5D8bh39BPv7y3PrUNVMQdKEJp_D5oJ0ROPTIYx3EG8eJQOx1HO0KqhcUo401XR6KSsIyFm5joBLNKTVzxZUTT1RRZZtwTdeZkbGevugIOX_9gHAtARpV6WaFA4Vvjnq8X9wPgqjWNCQRupadhTPz0JAsa-wy5vXQjsFlXAn43mDPpMfna5Ab3F5pS4yDwkbX6nRn7XBxH1SnnNJRFholQZw"' To iSuccess
Get ComAppend Of hoSbJws " }," To iSuccess
Get ComAppend Of hoSbJws " { " To iSuccess
Get ComAppend Of hoSbJws ' "protected": "eyJhbGciOiJFUzI1NiIsImtpZCI6Im15RWNLZXkifQ",' To iSuccess
Get ComAppend Of hoSbJws ' "signature": "1OQtaT3pgZmkDxvlfghvxL_8kX16WIen6u1MadEq1pA4qytA0--_EwZDNk00GDPWFpoJtKznibMZzLOg_UhHIw"' To iSuccess
Get ComAppend Of hoSbJws " }," To iSuccess
Get ComAppend Of hoSbJws " { " To iSuccess
Get ComAppend Of hoSbJws ' "protected": "eyJhbGciOiJIUzI1NiIsImtpZCI6Im15TWFjS2V5In0",' To iSuccess
Get ComAppend Of hoSbJws ' "signature": "YY8yVjmJJfy7YJOn3uUydG8WCY2PEuCvOLil5Ks5lnw"' To iSuccess
Get ComAppend Of hoSbJws " }" To iSuccess
Get ComAppend Of hoSbJws " ]" To iSuccess
Get ComAppend Of hoSbJws "}" To iSuccess
Get Create (RefClass(cComChilkatJws)) To hoJws
If (Not(IsComObjectCreated(hoJws))) Begin
Send CreateComObject of hoJws
End
Get pvComObject of hoSbJws to vSbJws
Get ComLoadJwsSb Of hoJws vSbJws To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoJws To sTemp1
Showln sTemp1
Procedure_Return
End
// The payload is easily accessible:
Get ComGetPayload Of hoJws "utf-8" To sTemp1
Showln "Payload: " sTemp1
Get Create (RefClass(cComChilkatStringBuilder)) To hoSbKeyId
If (Not(IsComObjectCreated(hoSbKeyId))) Begin
Send CreateComObject of hoSbKeyId
End
Move False To iBCaseSensitive
Get Create (RefClass(cComChilkatJsonObject)) To hoProtHeader
If (Not(IsComObjectCreated(hoProtHeader))) Begin
Send CreateComObject of hoProtHeader
End
Get ComNumSignatures Of hoJws To iNumSignatures
Move 0 To i
While (i < iNumSignatures)
Get pvComObject of hoProtHeader to vProtHeader
Get ComGetProtectedH Of hoJws i vProtHeader To iSuccess
If (iSuccess = False) Begin
Get ComLastErrorText Of hoJws To sTemp1
Showln sTemp1
Procedure_Return
End
Showln "--------------------------"
Showln i ": "
// Get the protected header.
Set ComEmitCompact Of hoProtHeader To False
Get ComEmit Of hoProtHeader To sTemp1
Showln sTemp1
// Get the key ID ("kid") member.
// Note: In this example, the "kid" values are contained in the protected headers.
// They could've just as easily been located in unprotected headers. In that case,
// we would've called GetUnprotectedH instead of GetProtectedH(i).
Send ComClear To hoSbKeyId
Get ComStringOf Of hoProtHeader "kid" To sTemp1
Get ComAppend Of hoSbKeyId sTemp1 To iSuccess
// Set the key based on key ID.
Get ComContentsEqual Of hoSbKeyId "myRsaKey" iBCaseSensitive To bTemp1
If (bTemp1 = True) Begin
Get pvComObject of hoRsaKey to vRsaKey
Get ComSetPublicKey Of hoJws i vRsaKey To iSuccess
End
Get ComContentsEqual Of hoSbKeyId "myEcKey" iBCaseSensitive To bTemp1
If (bTemp1 = True) Begin
Get pvComObject of hoEccKey to vEccKey
Get ComSetPublicKey Of hoJws i vEccKey To iSuccess
End
Get ComContentsEqual Of hoSbKeyId "myMacKey" iBCaseSensitive To bTemp1
If (bTemp1 = True) Begin
Get ComSetMacKey Of hoJws i sHmacKey "base64url" To iSuccess
End
// Validate this signature.
Get ComValidate Of hoJws i To v
If (v < 0) Begin
// Perhaps Chilkat was not unlocked or the trial expired..
Showln "Validate failed for some other reason."
Get ComLastErrorText Of hoJws To sTemp1
Showln sTemp1
End
Else Begin
If (v = 0) Begin
Showln "Invalid signature. The key was incorrect, the JWS was invalid, or both."
End
Else Begin
Showln "Signature validated."
End
End
Move (i + 1) To i
Loop
// The output of this program is:
// Payload: In our village, folks say God crumbles up the old moon into stars.
// --------------------------
// 0:
// {
// "alg": "RS256",
// "kid": "myRsaKey"
// }
//
// Signature validated.
// --------------------------
// 1:
// {
// "alg": "ES256",
// "kid": "myEcKey"
// }
//
// Signature validated.
// --------------------------
// 2:
// {
// "alg": "HS256",
// "kid": "myMacKey"
// }
//
// Signature validated.
End_Procedure