Sample code for 30+ languages & platforms
SQL Server Requires Chilkat v11.6.0+

Derive a Key from a Password with Argon2

Demonstrates Crypt2.Argon2DeriveKey, which derives a key from a password using Argon2. The options JSON requires a salt (chosen and stored by the application) and accepts the cost parameters variant, version, iterations, memoryCostKb, parallelism, and keyLen.

Background. Argon2 (RFC 9106) is a memory-hard function that is deliberately expensive in CPU time and memory, which is what makes brute-forcing the password space costly. The argon2id variant is recommended unless there is a specific reason to choose argon2i or argon2d. memoryCostKb does the most to make an attack expensive. The salt, cost parameters, and options must be stored so the same key can be re-derived.

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 @success int
    SELECT @success = 0

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

    --  The password should come from a secure source rather than being hard-coded.
    DECLARE @password nvarchar(4000)
    SELECT @password = 'correct horse battery staple'

    --  A key-derivation salt is chosen and stored by the application.  Generate 16 random bytes and use
    --  them (base64) as the salt.  The salt encoding defaults to base64.
    EXEC sp_OASetProperty @crypt, 'EncodingMode', 'base64'
    DECLARE @saltB64 nvarchar(4000)
    EXEC sp_OAMethod @crypt, 'GenRandomBytesENC', @saltB64 OUT, 16

    --  Build the Argon2 options JSON.  Only "salt" is required; every other member is optional and shown
    --  here with a typical explicit value:
    --    variant       argon2id (default), argon2i, or argon2d
    --    version       19 (default, 0x13) or 16 (0x10)
    --    iterations    passes over memory (t), >= 1, default 3
    --    memoryCostKb  memory in KB (m), >= 8*parallelism, default 65536 (64 MB)
    --    parallelism   lanes (p), default 1
    --    keyLen        derived key length in bytes, 4..1048576, default 32
    DECLARE @json int
    EXEC @hr = sp_OACreate 'Chilkat.JsonObject', @json OUT

    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'variant', 'argon2id'
    EXEC sp_OAMethod @json, 'UpdateInt', @success OUT, 'version', 19
    EXEC sp_OAMethod @json, 'UpdateInt', @success OUT, 'iterations', 3
    EXEC sp_OAMethod @json, 'UpdateInt', @success OUT, 'memoryCostKb', 65536
    EXEC sp_OAMethod @json, 'UpdateInt', @success OUT, 'parallelism', 1
    EXEC sp_OAMethod @json, 'UpdateInt', @success OUT, 'keyLen', 32
    EXEC sp_OAMethod @json, 'UpdateString', @success OUT, 'salt', @saltB64

    --  Derive the key.  The derived key is returned in the BinData (cleared first).
    DECLARE @bdKey int
    EXEC @hr = sp_OACreate 'Chilkat.BinData', @bdKey OUT

    EXEC sp_OAMethod @json, 'Emit', @sTmp0 OUT
    EXEC sp_OAMethod @crypt, 'Argon2DeriveKey', @success OUT, @password, @sTmp0, @bdKey
    IF @success = 0
      BEGIN
        EXEC sp_OAGetProperty @crypt, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @crypt
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @bdKey
        RETURN
      END

    --  The application stores the salt and cost parameters so the same key can be re-derived later.
    DECLARE @keyHex nvarchar(4000)
    EXEC sp_OAMethod @bdKey, 'GetEncoded', @keyHex OUT, 'hex'
    EXEC sp_OAGetProperty @bdKey, 'LastMethodSuccess', @iTmp0 OUT
    IF @iTmp0 = 0
      BEGIN
        EXEC sp_OAGetProperty @bdKey, 'LastErrorText', @sTmp0 OUT
        PRINT @sTmp0
        EXEC @hr = sp_OADestroy @crypt
        EXEC @hr = sp_OADestroy @json
        EXEC @hr = sp_OADestroy @bdKey
        RETURN
      END

    EXEC sp_OAGetProperty @bdKey, 'NumBytes', @iTmp0 OUT

    PRINT 'Derived ' + @iTmp0 + '-byte key: ' + @keyHex

    EXEC @hr = sp_OADestroy @crypt
    EXEC @hr = sp_OADestroy @json
    EXEC @hr = sp_OADestroy @bdKey


END
GO