SQL Server
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
-- 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