Sample code for 30+ languages & platforms
SQL Server

Decrypt a JWE to a String

See more JSON Web Encryption (JWE) Examples

Demonstrates Jwe.Decrypt, which decrypts a recipient of a loaded JWE and returns the plaintext, decoded using the given charset. Before decrypting, the example inspects the JWE protected header and, under application policy, accepts only permitted algorithms and selects an acceptable recipient.

Background. A received JWE should never be trusted to specify safe algorithms. The example reads the alg and enc values from the protected header (via GetProtectedHeader) and enforces an allowlist, rejecting anything not permitted. It then selects the recipient the application holds a key for — using FindRecipient to locate a recipient by a per-recipient header value such as kid, falling back to index 0 for a single-recipient compact JWE — and only then supplies the key and decrypts.

Chilkat SQL Server Downloads

SQL Server
-- Important: See this note about string length limitations for strings returned by sp_OAMethod calls.
--
CREATE PROCEDURE ChilkatSample
AS
BEGIN
    DECLARE @hr int
    DECLARE @iTmp0 int
    DECLARE @sTmp0 nvarchar(4000)
    DECLARE @sTmp1 nvarchar(4000)
    DECLARE @success int
    SELECT @success = 0

    DECLARE @jwe int
    EXEC @hr = sp_OACreate 'Chilkat.Jwe', @jwe OUT
    IF @hr <> 0
    BEGIN
        PRINT 'Failed to create ActiveX component'
        RETURN
    END

    --  Load the JWE compact serialization to be decrypted.
    DECLARE @jweCompact nvarchar(4000)
    SELECT @jweCompact = 'eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIn0.<...>.<iv>.<ciphertext>.<tag>'
    EXEC sp_OAMethod @jwe, 'LoadJwe', @success OUT, @jweCompact
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @jwe, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @jwe
        RETURN
      END

    --  Application policy: before decrypting, inspect the JWE header and accept only algorithms the
    --  application trusts.  Never assume the algorithms in a received JWE are safe -- a sender could
    --  specify a weak or unexpected algorithm.
    DECLARE @protHeader int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @protHeader OUT

    EXEC sp_OAMethod @jwe, 'GetProtectedHeader', @success OUT, @protHeader
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @jwe, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @jwe
        EXEC @hr = sp_OADestroy @protHeader
        RETURN
      END

    --  Read the alg (key-management) and enc (content-encryption) header values into StringBuilder
    --  objects so they can be compared.
    DECLARE @sbAlg int
    EXEC @hr = sp_OACreate 'Chilkat.StringBuilder', @sbAlg OUT

    EXEC sp_OAMethod @protHeader, 'StringOfSb', @success OUT, 'alg', @sbAlg
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @protHeader, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @jwe
        EXEC @hr = sp_OADestroy @protHeader
        EXEC @hr = sp_OADestroy @sbAlg
        RETURN
      END
    DECLARE @sbEnc int
    EXEC @hr = sp_OACreate 'Chilkat.StringBuilder', @sbEnc OUT

    EXEC sp_OAMethod @protHeader, 'StringOfSb', @success OUT, 'enc', @sbEnc
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @protHeader, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @jwe
        EXEC @hr = sp_OADestroy @protHeader
        EXEC @hr = sp_OADestroy @sbAlg
        EXEC @hr = sp_OADestroy @sbEnc
        RETURN
      END

    EXEC sp_OAMethod @sbAlg, 'GetAsString', @sTmp0 OUT

    EXEC sp_OAMethod @sbEnc, 'GetAsString', @sTmp1 OUT
    PRINT 'JWE algorithms: alg=' + @sTmp0 + ' enc=' + @sTmp1

    --  Enforce an allowlist of acceptable algorithms.  Reject anything not permitted by policy.  String
    --  values are compared using StringBuilder.ContentsEqual.
    DECLARE @bCaseSensitive int
    SELECT @bCaseSensitive = 1
    EXEC sp_OAMethod @sbAlg, 'ContentsEqual', @iTmp0 OUT, 'A256KW', @bCaseSensitive
    IF @iTmp0 <> 1
      BEGIN

        PRINT 'Rejecting JWE: key-management algorithm is not permitted by policy.'
        EXEC @hr = sp_OADestroy @jwe
        EXEC @hr = sp_OADestroy @protHeader
        EXEC @hr = sp_OADestroy @sbAlg
        EXEC @hr = sp_OADestroy @sbEnc
        RETURN
      END
    EXEC sp_OAMethod @sbEnc, 'ContentsEqual', @iTmp0 OUT, 'A256GCM', @bCaseSensitive
    IF @iTmp0 <> 1
      BEGIN

        PRINT 'Rejecting JWE: content-encryption algorithm is not permitted by policy.'
        EXEC @hr = sp_OADestroy @jwe
        EXEC @hr = sp_OADestroy @protHeader
        EXEC @hr = sp_OADestroy @sbAlg
        EXEC @hr = sp_OADestroy @sbEnc
        RETURN
      END

    --  Select an acceptable recipient.  For a multi-recipient JWE, FindRecipient locates the recipient
    --  this application holds a key for by a per-recipient header value such as "kid".  A compact JWE
    --  has a single recipient at index 0, so FindRecipient returns -1; fall back to index 0 in that case.
    DECLARE @recipientIndex int
    EXEC sp_OAMethod @jwe, 'FindRecipient', @recipientIndex OUT, 'kid', 'recipient-key-1', @bCaseSensitive
    IF @recipientIndex < 0
      BEGIN
        SELECT @recipientIndex = 0
      END

    --  Provide the key for the selected recipient.  In production, obtain the key from a secure source
    --  rather than hard-coding it.
    DECLARE @base64Key nvarchar(4000)
    SELECT @base64Key = 'YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU='
    EXEC sp_OAMethod @jwe, 'SetWrappingKey', @success OUT, @recipientIndex, @base64Key, 'base64'
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @jwe, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @jwe
        EXEC @hr = sp_OADestroy @protHeader
        EXEC @hr = sp_OADestroy @sbAlg
        EXEC @hr = sp_OADestroy @sbEnc
        RETURN
      END

    --  Decrypt the selected recipient and return the plaintext, decoded using the given charset.
    DECLARE @content nvarchar(4000)
    EXEC sp_OAMethod @jwe, 'Decrypt', @content OUT, @recipientIndex, 'utf-8'
    EXEC sp_OAGetProperty @jwe, 'LastMethodSuccess', @iTmp0 OUT
    IF @iTmp0 = 0
      BEGIN
        EXEC sp_OAGetProperty @jwe, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @jwe
        EXEC @hr = sp_OADestroy @protHeader
        EXEC @hr = sp_OADestroy @sbAlg
        EXEC @hr = sp_OADestroy @sbEnc
        RETURN
      END

    PRINT @content

    EXEC @hr = sp_OADestroy @jwe
    EXEC @hr = sp_OADestroy @protHeader
    EXEC @hr = sp_OADestroy @sbAlg
    EXEC @hr = sp_OADestroy @sbEnc


END
GO