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

Argon2 Key Derivation with a Secret (Pepper), AD, and Encodings

Demonstrates the optional Argon2 options for Crypt2.Argon2DeriveKey: secret (a pepper), ad (associated data), the encoding member and its per-member overrides saltEncoding/secretEncoding/adEncoding, passwordCharset, and maxMemoryKb.

Background. A pepper is a secret value held by the application and not stored with the hash, so a stolen hash database cannot be attacked without it. The encoding members control how the salt, secret, and ad text are interpreted as bytes (base64 by default; utf-8 uses the characters themselves). maxMemoryKb is a guard against an unreasonable memory cost.

Chilkat DataFlex Downloads

DataFlex
Use ChilkatAx-win32.pkg

Procedure Test
    Boolean iSuccess
    Handle hoCrypt
    String sPassword
    Handle hoJson
    Variant vBdKey
    Handle hoBdKey
    String sKeyHex
    String sTemp1
    Boolean bTemp1

    Move False To iSuccess

    Get Create (RefClass(cComChilkatCrypt2)) To hoCrypt
    If (Not(IsComObjectCreated(hoCrypt))) Begin
        Send CreateComObject of hoCrypt
    End

    //  The password should come from a secure source rather than being hard-coded.
    Move "correct horse battery staple" To sPassword

    //  Build the Argon2 options JSON, this time using the optional secret, ad, and encoding members.
    //    secret         the RFC 9106 secret value K, often called a "pepper": a key held by the
    //                   application and NOT stored with the hash, so a stolen hash database cannot be
    //                   attacked without it.
    //    ad             optional associated data X: additional non-secret data bound into the derivation.
    //    encoding       how salt, secret, and ad are encoded (default base64).  Per-member overrides are
    //                   saltEncoding, secretEncoding, and adEncoding.
    //    passwordCharset  the charset the password is converted to before use (default utf-8).
    //    maxMemoryKb    a guard (not an Argon2 parameter) refusing to allocate more than this many KB;
    //                   default 2097152 (2 GB).
    Get Create (RefClass(cComChilkatJsonObject)) To hoJson
    If (Not(IsComObjectCreated(hoJson))) Begin
        Send CreateComObject of hoJson
    End

    //  The salt is provided here as hex, overriding the default base64 for just this member.
    Get ComUpdateString Of hoJson "salt" "0102030405060708090a0b0c0d0e0f10" To iSuccess
    Get ComUpdateString Of hoJson "saltEncoding" "hex" To iSuccess

    //  The pepper is supplied as UTF-8 text (its own characters are the bytes).
    Get ComUpdateString Of hoJson "secret" "application-wide-pepper" To iSuccess
    Get ComUpdateString Of hoJson "secretEncoding" "utf-8" To iSuccess

    //  Associated data, supplied as UTF-8 text.
    Get ComUpdateString Of hoJson "ad" "user-id-42" To iSuccess
    Get ComUpdateString Of hoJson "adEncoding" "utf-8" To iSuccess

    Get ComUpdateString Of hoJson "passwordCharset" "utf-8" To iSuccess
    Get ComUpdateInt Of hoJson "maxMemoryKb" 1048576 To iSuccess
    Get ComUpdateInt Of hoJson "keyLen" 32 To iSuccess

    Get Create (RefClass(cComChilkatBinData)) To hoBdKey
    If (Not(IsComObjectCreated(hoBdKey))) Begin
        Send CreateComObject of hoBdKey
    End
    Get ComEmit Of hoJson To sTemp1
    Get pvComObject of hoBdKey to vBdKey
    Get ComArgon2DeriveKey Of hoCrypt sPassword sTemp1 vBdKey To iSuccess
    If (iSuccess = False) Begin
        Get ComLastErrorText Of hoCrypt To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Get ComGetEncoded Of hoBdKey "hex" To sKeyHex
    Get ComLastMethodSuccess Of hoBdKey To bTemp1
    If (bTemp1 = False) Begin
        Get ComLastErrorText Of hoBdKey To sTemp1
        Showln sTemp1
        Procedure_Return
    End

    Showln "Derived key: " sKeyHex


End_Procedure