• Welcome to PlanetSquires Forums.
 

Returning

Started by Richard Kelly, September 02, 2022, 02:45:08 AM

Previous topic - Next topic

Richard Kelly

It's been a bit time since my last appearance. COVID has been a major restructuring of life style and I've also moved 3 times in last several years.

With retirement looming, I've been focused on my career as a software engineer for a large glocal company and just didn't have the resolve to continue coding with Freebasic in the evenings.

I've decided to reactivate Freebasic as a retirement hobby and pace myself and keep life in balance.

As memory recalls, I left off designing a set of SQLite client/server classes and I think I'll kinda start over and rebuild it back up.
It all begins with a connection between client and server and originally I made up a basically low grade encryption not terribly secure.

Let's see where it goes from here...be patient. I'm going to be doing incremental stuff as time permits.

Today, I put together a BCrypt based Diffie/Hellman public key exchange that has the potential to be very secure.


Simple console program tested with 32/64 bit compiles. No error checking, just a proof of concept check.

#Define UNICODE
#Include Once "windows.bi"
#Include Once "win\bcrypt.bi"
#Include Once "win\wincrypt.bi"
#Inclib "bcrypt"
#Inclib "crypt32"
SUB Bin2Hex(BYREF sBinary AS STRING, _
            BYREF sHex AS STRING)
' Convert binary string to hex representation
dim nHexLength    AS LONG
    sHex = ""
    nHexLength = LEN(sBinary) * 2
    IF LEN(nHexLength) > 0 THEN
        nHexLength = nHexLength + 1
        sHex = SPACE$(nHexLength)
        CryptBinaryToStringA(STRPTR(sBinary), _
                            LEN(sBinary), _
                            CRYPT_STRING_HEXRAW + CRYPT_STRING_NOCRLF, _
                            STRPTR(sHex), _
                            varptr(nHexLength))
         sHex = LEFT$(sHex,nHexLength)
    END IF
END SUB
dim lStatus              AS NTSTATUS
dim hMyAlgorithm         as BCRYPT_ALG_HANDLE
dim hMyKey               as BCRYPT_KEY_HANDLE
dim hMyKeyImport         as BCRYPT_KEY_HANDLE
dim hMySecret            as BCRYPT_SECRET_HANDLE
dim MyPublicKey          as string
dim MyKeySize            as ulong
dim MyDerivedKeySize     as ulong
dim MyDerivedKey         as string
dim hOtherAlgorithm      as BCRYPT_ALG_HANDLE
dim hOtherKey            as BCRYPT_KEY_HANDLE
dim hOtherKeyImport      as BCRYPT_KEY_HANDLE
dim hOtherSecret         as BCRYPT_SECRET_HANDLE
dim OtherPublicKey       as string
dim OtherKeySize         as ulong
dim OtherDerivedKeySize  as ulong
dim OtherDerivedKey      as string
dim sHex                 as string

' Open Algorithm Provider
lStatus = BCryptOpenAlgorithmProvider(varptr(hMyAlgorithm), strptr(BCRYPT_ECDH_P384_ALGORITHM), strptr(MS_PRIMITIVE_PROVIDER), 0)
' Generate Key Pair
lStatus = BCryptGenerateKeyPair(hMyAlgorithm, varptr(hMyKey), 384, 0)
lStatus = BCryptFinalizeKeyPair(hMyKey,0)
' The public key then needs to be exported and passed to the other side of the secret exchange
' Get the size of the key
lStatus = BCryptExportKey(hMyKey, Null, strptr(BCRYPT_ECCPUBLIC_BLOB), Null, 0, varptr(MyKeySize), 0)
' Initialize Public Key to required size
MyPublicKey = space(MyKeySize)
' Get My Public Key
lStatus = BCryptExportKey(hMyKey, Null, strptr(BCRYPT_ECCPUBLIC_BLOB), strptr(MyPublicKey), MyKeySize, varptr(MyKeySize), 0)
' Let's look at public key
Bin2Hex(MyPublicKey,sHex)
Print "My Public Key"
print sHex
print ""
' Simulate sending our public key to the "other" side, get their public key and we both derive the shared symmetric key
' Open Algorithm Provider
lStatus = BCryptOpenAlgorithmProvider(varptr(hOtherAlgorithm), strptr(BCRYPT_ECDH_P384_ALGORITHM), strptr(MS_PRIMITIVE_PROVIDER), 0)
' Generate Key Pair
lStatus = BCryptGenerateKeyPair(hOtherAlgorithm, varptr(hOtherKey), 384, 0)
lStatus = BCryptFinalizeKeyPair(hOtherKey,0)
' The public key then needs to be exported and passed to the other side of the secret exchange
' ***** Other Side *****
' Get the size of the key
lStatus = BCryptExportKey(hOtherKey, Null, strptr(BCRYPT_ECCPUBLIC_BLOB), Null, 0, varptr(OtherKeySize), 0)
' Initialize Public Key to required size
OtherPublicKey = space(OtherKeySize)
' Get Other Public Key
lStatus = BCryptExportKey(hOtherKey, Null, strptr(BCRYPT_ECCPUBLIC_BLOB), strptr(OtherPublicKey), OtherKeySize, varptr(OtherKeySize), 0)
' Let's look at public key
Bin2Hex(OtherPublicKey,sHex)
Print "Other Public Key"
print sHex
print ""
' Import Public key by Other Party From Me
lStatus = BCryptImportKeyPair(hOtherAlgorithm, Null, strptr(BCRYPT_ECCPUBLIC_BLOB), varptr(hOtherKeyImport), strptr(MyPublicKey), Len(MyPublicKey), 0)
' Create the secret
lStatus = BCryptSecretAgreement(hOtherKey, hOtherKeyImport, varptr(hOtherSecret), 0)
' Once the secret handle has been generated, a symmetric key can be derived.
' Get Derived Key Size
lStatus = BCryptDeriveKey(hOtherSecret, strptr(BCRYPT_KDF_HASH), Null, Null, 0, varptr(OtherDerivedKeySize), 0)
OtherDerivedKey = space(OtherDerivedKeySize)
lStatus = BCryptDeriveKey(hOtherSecret, strptr(BCRYPT_KDF_HASH), Null, strptr(OtherDerivedKey), OtherDerivedKeySize, varptr(OtherDerivedKeySize), 0)
' Let's look at derived key
Bin2Hex(OtherDerivedKey,sHex)
Print "Other Shared Derived Session Key"
print sHex
print ""
' ***** My Side after receiving Other side public key *****
' Import Public key by My From Other Party
lStatus = BCryptImportKeyPair(hOtherAlgorithm, Null, strptr(BCRYPT_ECCPUBLIC_BLOB), varptr(hMyKeyImport), strptr(OtherPublicKey), Len(OtherPublicKey), 0)
' Create the secret
lStatus = BCryptSecretAgreement(hMyKey, hMyKeyImport, varptr(hMySecret), 0)
' Once the secret handle has been generated, a symmetric key can be derived.
' Get Derived Key Size
lStatus = BCryptDeriveKey(hMySecret, strptr(BCRYPT_KDF_HASH), Null, Null, 0, varptr(MyDerivedKeySize), 0)
MyDerivedKey = space(MyDerivedKeySize)
lStatus = BCryptDeriveKey(hMySecret, strptr(BCRYPT_KDF_HASH), Null, strptr(MyDerivedKey), MyDerivedKeySize, varptr(MyDerivedKeySize), 0)
' Let's look at derived key
Bin2Hex(MyDerivedKey,sHex)
Print "My Shared Derived Session Key"
print sHex
print ""
if MyDerivedKey = OtherDerivedKey then
print "Derived Session Keys Match!"
else
    print "Error - Derived Session Keys do not match!"
end if
' Clean up all our handles
lStatus = BCryptDestroyKey(hOtherKeyImport)
lStatus = BCryptDestroySecret(hOtherSecret)
lStatus = BCryptCloseAlgorithmProvider(hOtherAlgorithm, 0)
lStatus = BCryptCloseAlgorithmProvider(hMyAlgorithm, 0)
lStatus = BCryptDestroyKey(hMyKeyImport)
lStatus = BCryptDestroySecret(hMySecret)
Print
Print "Press any key..."
Sleep

Paul Squires

Welcome back Richard! My retirement is looming as well   8)
Paul Squires
PlanetSquires Software
WinFBE Editor and Visual Designer