Sample code for 30+ languages & platforms
PowerBuilder

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 PowerBuilder Downloads

PowerBuilder
integer li_rc
integer li_Success
oleobject loo_SbRsaJwk
oleobject loo_RsaKey
oleobject loo_SbEccJwk
oleobject loo_EccKey
string ls_HmacKey
oleobject loo_SbJws
oleobject loo_Jws
oleobject loo_SbKeyId
integer li_BCaseSensitive
oleobject loo_ProtHeader
integer li_NumSignatures
integer i
integer v

li_Success = 0

// 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.
loo_SbRsaJwk = create oleobject
li_rc = loo_SbRsaJwk.ConnectToNewObject("Chilkat.StringBuilder")
if li_rc < 0 then
    destroy loo_SbRsaJwk
    MessageBox("Error","Connecting to COM object failed")
    return
end if
loo_SbRsaJwk.Append("{~"kty~":~"RSA~",")
loo_SbRsaJwk.Append("~"n~":~"ofgWCuLjybRlzo0tZWJjNiuSfb4p4fAkd_wWJcyQoTbji9k0l8W26mPddx")
loo_SbRsaJwk.Append("HmfHQp-Vaw-4qPCJrcS2mJPMEzP1Pt0Bm4d4QlL-yRT-SFd2lZS-pCgNMs")
loo_SbRsaJwk.Append("D1W_YpRPEwOWvG6b32690r2jZ47soMZo9wGzjb_7OMg0LOL-bSf63kpaSH")
loo_SbRsaJwk.Append("SXndS5z5rexMdbBYUsLA9e-KXBdQOS-UTo7WTBEMa2R2CapHg665xsmtdV")
loo_SbRsaJwk.Append("MTBQY4uDZlxvb3qCo5ZwKh9kG4LT6_I5IhlJH7aGhyxXFvUK-DWNmoudF8")
loo_SbRsaJwk.Append("NAco9_h9iaGNj8q2ethFkMLs91kzk2PAcDTW9gb54h4FRWyuXpoQ~",")
loo_SbRsaJwk.Append("~"e~":~"AQAB~"")
loo_SbRsaJwk.Append("}")

loo_RsaKey = create oleobject
li_rc = loo_RsaKey.ConnectToNewObject("Chilkat.PublicKey")

li_Success = loo_RsaKey.LoadFromString(loo_SbRsaJwk.GetAsString())
if li_Success = 0 then
    Write-Debug loo_RsaKey.LastErrorText
    destroy loo_SbRsaJwk
    destroy loo_RsaKey
    return
end if

// ---------------------------------------------------
// Use the following ECC public key loaded from JWK format.
loo_SbEccJwk = create oleobject
li_rc = loo_SbEccJwk.ConnectToNewObject("Chilkat.StringBuilder")

loo_SbEccJwk.Append("{~"kty~":~"EC~",")
loo_SbEccJwk.Append("~"crv~":~"P-256~",")
loo_SbEccJwk.Append("~"x~":~"f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU~",")
loo_SbEccJwk.Append("~"y~":~"x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0~"")
loo_SbEccJwk.Append("}")

loo_EccKey = create oleobject
li_rc = loo_EccKey.ConnectToNewObject("Chilkat.PublicKey")

li_Success = loo_EccKey.LoadFromString(loo_SbEccJwk.GetAsString())
if li_Success = 0 then
    Write-Debug loo_EccKey.LastErrorText
    destroy loo_SbRsaJwk
    destroy loo_RsaKey
    destroy loo_SbEccJwk
    destroy loo_EccKey
    return
end if

// ---------------------------------------------------
// The HMAC key (in base64url format)
ls_HmacKey = "AyM1SysPpbyDfgZld3umj1qzKObwVMkoqQ-EstJQLr_T-1qS0gZH75aKtMN3Yj0iPS4hcgUuTwjAzZr1Z9CAow"

// 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"
//     }
//   ]
// }

loo_SbJws = create oleobject
li_rc = loo_SbJws.ConnectToNewObject("Chilkat.StringBuilder")

loo_SbJws.Append("{ ")
loo_SbJws.Append("  ~"payload~": ~"SW4gb3VyIHZpbGxhZ2UsIGZvbGtzIHNheSBHb2QgY3J1bWJsZXMgdXAgdGhlIG9sZCBtb29uIGludG8gc3RhcnMu~",")
loo_SbJws.Append("  ~"signatures~": [")
loo_SbJws.Append("    { ")
loo_SbJws.Append("      ~"protected~": ~"eyJhbGciOiJSUzI1NiIsImtpZCI6Im15UnNhS2V5In0~",")
loo_SbJws.Append("      ~"signature~": ~"IPMQ02niTQDwLzsRZSCaEm9VEyAX_AVe3HWjniNt9kW-a8d6ZVbd2k6jGae8s1yIh0cgxDnXQ6-p6_sBI0cnMO0xpuJANhh2vFtNJl5lisad94-H3mB3lSfafRqxeYp5D8bh39BPv7y3PrUNVMQdKEJp_D5oJ0ROPTIYx3EG8eJQOx1HO0KqhcUo401XR6KSsIyFm5joBLNKTVzxZUTT1RRZZtwTdeZkbGevugIOX_9gHAtARpV6WaFA4Vvjnq8X9wPgqjWNCQRupadhTPz0JAsa-wy5vXQjsFlXAn43mDPpMfna5Ab3F5pS4yDwkbX6nRn7XBxH1SnnNJRFholQZw~"")
loo_SbJws.Append("    },")
loo_SbJws.Append("    { ")
loo_SbJws.Append("      ~"protected~": ~"eyJhbGciOiJFUzI1NiIsImtpZCI6Im15RWNLZXkifQ~",")
loo_SbJws.Append("      ~"signature~": ~"1OQtaT3pgZmkDxvlfghvxL_8kX16WIen6u1MadEq1pA4qytA0--_EwZDNk00GDPWFpoJtKznibMZzLOg_UhHIw~"")
loo_SbJws.Append("    },")
loo_SbJws.Append("    { ")
loo_SbJws.Append("      ~"protected~": ~"eyJhbGciOiJIUzI1NiIsImtpZCI6Im15TWFjS2V5In0~",")
loo_SbJws.Append("      ~"signature~": ~"YY8yVjmJJfy7YJOn3uUydG8WCY2PEuCvOLil5Ks5lnw~"")
loo_SbJws.Append("    }")
loo_SbJws.Append("  ]")
loo_SbJws.Append("}")

loo_Jws = create oleobject
li_rc = loo_Jws.ConnectToNewObject("Chilkat.Jws")

li_Success = loo_Jws.LoadJwsSb(loo_SbJws)
if li_Success = 0 then
    Write-Debug loo_Jws.LastErrorText
    destroy loo_SbRsaJwk
    destroy loo_RsaKey
    destroy loo_SbEccJwk
    destroy loo_EccKey
    destroy loo_SbJws
    destroy loo_Jws
    return
end if

// The payload is easily accessible:
Write-Debug "Payload: " + loo_Jws.GetPayload("utf-8")

loo_SbKeyId = create oleobject
li_rc = loo_SbKeyId.ConnectToNewObject("Chilkat.StringBuilder")

li_BCaseSensitive = 0

loo_ProtHeader = create oleobject
li_rc = loo_ProtHeader.ConnectToNewObject("Chilkat.JsonObject")

li_NumSignatures = loo_Jws.NumSignatures
i = 0
do while i < li_NumSignatures
    li_Success = loo_Jws.GetProtectedH(i,loo_ProtHeader)
    if li_Success = 0 then
        Write-Debug loo_Jws.LastErrorText
        destroy loo_SbRsaJwk
        destroy loo_RsaKey
        destroy loo_SbEccJwk
        destroy loo_EccKey
        destroy loo_SbJws
        destroy loo_Jws
        destroy loo_SbKeyId
        destroy loo_ProtHeader
        return
    end if

    Write-Debug "--------------------------"
    Write-Debug string(i) + ": "

    // Get the protected header.
    loo_ProtHeader.EmitCompact = 0
    Write-Debug loo_ProtHeader.Emit()

    // 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).

    loo_SbKeyId.Clear()
    loo_SbKeyId.Append(loo_ProtHeader.StringOf("kid"))

    // Set the key based on key ID.
    if loo_SbKeyId.ContentsEqual("myRsaKey",li_BCaseSensitive) = 1 then
        loo_Jws.SetPublicKey(i,loo_RsaKey)
    end if

    if loo_SbKeyId.ContentsEqual("myEcKey",li_BCaseSensitive) = 1 then
        loo_Jws.SetPublicKey(i,loo_EccKey)
    end if

    if loo_SbKeyId.ContentsEqual("myMacKey",li_BCaseSensitive) = 1 then
        loo_Jws.SetMacKey(i,ls_HmacKey,"base64url")
    end if

    // Validate this signature.
    v = loo_Jws.Validate(i)
    if v < 0 then
        // Perhaps Chilkat was not unlocked or the trial expired..
        Write-Debug "Validate failed for some other reason."
        Write-Debug loo_Jws.LastErrorText
    else
        if v = 0 then
            Write-Debug "Invalid signature.  The key was incorrect, the JWS was invalid, or both."
        else
            Write-Debug "Signature validated."
        end if

    end if

    i = i + 1
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.


destroy loo_SbRsaJwk
destroy loo_RsaKey
destroy loo_SbEccJwk
destroy loo_EccKey
destroy loo_SbJws
destroy loo_Jws
destroy loo_SbKeyId
destroy loo_ProtHeader