Usage of CryptoSys API with PureBasic

Share your advanced PureBasic knowledge/code with the community.
User avatar
Kukulkan
Addict
Addict
Posts: 1396
Joined: Mon Jun 06, 2005 2:35 pm
Location: germany
Contact:

Usage of CryptoSys API with PureBasic

Post by Kukulkan »

Hi,

I am using CryptoSys API in some commercial projects with good success. It is about 159 USD, but worth every dollar. You can find more information about this cryptographic library here: http://www.cryptosys.net/

Maybe you are interested in my implementation for reference? Here is a part of the include I wrote to use the library:

Code: Select all

; example for using CryptoSys API togehter with PureBasic V4.20

; FILE: CryptoSys_Include.pbi

; Description of CryptoSys API:
; The Original CryptoSys API provides four of the major block cipher
; algorithms: AES, DES, Triple DES and Blowfish; a stream cipher
; compatible with RC4; key wrap with AES and Triple DES; secure message
; digest hash algorithms SHA-1, SHA-224, SHA-256, SHA-384, SHA-512, MD5
; and MD2; the HMAC and CMAC message authentication algorithms,
; data compression, and a secure random number generator.

; Available at http://www.cryptosys.net/

#CryptLibrary = 1

Procedure.s OutToLog(strMessage.s)
  ; enter your error-handling code...
  Debug "Error-Log: " + strMessage.s
EndProcedure

; #############################
; ### CONVERTING FUNCTIONS  ###
; #############################
Procedure.s StringToHex(Original.s)
  ; Converts a normal string to HEX encoded string
  Protected Ergebnis.s, x.l
  
  Ergebnis.s = ""
  For x.l = 1 To Len(Original.s)
    Ergebnis.s = Ergebnis.s + RSet(Hex(Asc(Mid(Original.s, x.l, 1))), 2, "0")
  Next
  ProcedureReturn Ergebnis.s
EndProcedure

Procedure.l Hex2Dec(Input.s)
  ; converts a hex encoded number to decimal number (maximum long)
  ; examples: "FF" = 256  "65A" = 1626
  Protected i.l, d.l
  
  For i.l = 1 To Len(Input.s) 
    d.l = (d.l << 4) + Asc(UCase(Mid(Input.s, i.l, 1))) - 48 - 7 * (Asc(UCase(Mid(Input.s, i.l, 1))) >> 6) 
  Next 
  ProcedureReturn d.l
EndProcedure

Procedure.s HexToString(Original.s)
  ; converts a HEX encoded string into a normal string
  Protected Ergebnis.s, x.l
  
  Ergebnis.s = ""
  For x.l = 1 To Len(Original.s) Step 2
    Ergebnis.s = Ergebnis.s + Chr(Hex2Dec(Mid(Original.s, x.l, 2)))
  Next
  ProcedureReturn Ergebnis.s
EndProcedure


; ############################
; ### MANAGE CRYPTOSYS API ###
; ############################
Procedure.b InitCryptoDLL()
  ; init cryptosys API
  ; returns #True on success, otherwise #False
  If OpenLibrary(#CryptLibrary, "diCryptoSys.dll")
    *F.l = GetFunction(#CryptLibrary, "SHA2_Init")
    If *F.l = 0
      MessageRequester("Error", "Cant use diCryptoSys.dll. Please download the latest program-version and re-install.", #MB_ICONERROR)
      ProcedureReturn #False
    EndIf
  Else
    MessageRequester("Error", "Cant use diCryptoSys.dll. Please download the latest program-version and re-install.", #MB_ICONERROR)
    ProcedureReturn #False
  EndIf
  ; good!
  ProcedureReturn #True
EndProcedure

Procedure ShutdownCryptoDLL()
  ; shutdown cryptosys API
  CloseLibrary(#CryptLibrary)
EndProcedure

; ########################
; ### AES256 FUNCTIONS ###
; ########################
Procedure.l CryptFile_AES256(SourceFilename.s, DestinationFilename.s, KeyHEX.s, Encrypt.b)
  ; en- and decryption of files using AES256
  ; Key need to be HEX with 256Bit (32 chars are 64 chars in HEX)
  ; Encrypt = #True to encrypt
  ; Encrypt = #False to decrypt
  ; Returns 0 on success, -1 on error
  Protected r.l
  
  r.l = CallFunction(#CryptLibrary, "AES256_FileHex", @DestinationFilename.s, @SourceFilename.s, @KeyHEX.s, Encrypt.b, "ECB", "") 
  If r.l <> 0 
    OutToLog("ERROR: AES256_FileHex_Error : " + Str(r.l))
    ProcedureReturn -1
  EndIf 
  ProcedureReturn 0
EndProcedure

Procedure.s CryptStringHEX_AES256(SourceStringHEX.s, KeyHEX.s, Encrypt.b)
  ; en- and decryption of strings using AES256
  ; SourceString need to be HEX encoded!
  ; Key need to be HEX with 256Bit (32 chars are 64 chars in HEX)
  ; Encrypt = #True to encrypt
  ; Encrypt = #False to decrypt
  ; Returns HEX encoded result
  Protected HexDestination.s, r.l
  
  If SourceStringHEX.s = "": ProcedureReturn "": EndIf
  
  ; padding
  While Len(SourceStringHEX.s) % 32 <> 0
    ; not padded to 32 chars
    SourceStringHEX.s = SourceStringHEX.s + "00"
  Wend
  ;
  HexDestination.s = Space(Len(SourceStringHEX.s)) ; create empty space as buffer
  r.l = CallFunction(#CryptLibrary, "AES256_Hex", @HexDestination.s, @SourceStringHEX.s, @KeyHEX.s, Encrypt.b) 
  If r.l <> 0 
    OutToLog("ERROR: AES256_Hex_Error : " + Str(r.l)) 
    ProcedureReturn ""
  EndIf 
  ProcedureReturn HexDestination.s
EndProcedure

; ########################
; ### RANDOMIZE FUNCTIONS ###
; ########################
Procedure.s GenerateRandomHEX(Bitlength.l)
  ; generates a random number with Bitlength.l lengts (64, 128, 256, 512, 1024)
  ; result is the random number encoded in HEX
  Protected Bytes.l, key.s, r.l
  
  If Bitlength.l <> 64 And Bitlength.l <> 128 And Bitlength.l <> 256 And Bitlength.l <> 512 And Bitlength.l <> 1024
    OutToLog("ERROR: GenerateKey - unsupported bitlength: '" + Str(Bitlength.l) + "'")
    ProcedureReturn ""
  EndIf
  
  Bytes.l = Bitlength.l / 8
  key.s = Space(Bytes.l * 2)
  r.l = CallFunction(#CryptLibrary, "RNG_KeyHex", @key.s, Bytes.l * 2, Bytes.l, "", 0) 
  If r.l <> 0
    OutToLog("ERROR: RNG_KeyHex_Error : " + Str(r.l))
    ProcedureReturn ""
  Else
    ProcedureReturn key.s
  EndIf 
EndProcedure
This is working code. Here is a calling example:

Code: Select all

IncludeFile "CryptoSys_Include.pbi"

SampleText.s = "This is some simple text to test the functions."
Debug "original: " + SampleText.s

If InitCryptoDLL() = #True
  
  SamplePasswordHEX.s = GenerateRandomHEX(256) ; some 256 bit key
  Debug "random key: " + SamplePasswordHEX.s

  SampleTextHEX.s = StringToHex(SampleText.s) ; encode text in HEX (needed for CryptoSys)

  ; encrypt
  EncryptedHEX.s = CryptStringHEX_AES256(SampleTextHEX.s, SamplePasswordHEX.s, #True)
  Debug "encrypted: " + EncryptedHEX.s
  
  ; decrypt
  DecryptedHEX.s = CryptStringHEX_AES256(EncryptedHEX.s, SamplePasswordHEX.s, #False)
  Decrypted.s = HexToString(DecryptedHEX.s) ; decode HEX encoded result
  Debug "decrypted: " + Decrypted.s

  ShutdownCryptoDLL()
Else
  ; error initializing CryptoSys API

EndIf


There are a lot of other methods in this DLL that are not using HEX encoded values. It is able to use direct memory access and some good conversion routines.

By the way: this is no advertising. I am just a very happy customer and like to tell you about the good product. :wink:

Kukulkan
Last edited by Kukulkan on Fri Dec 12, 2008 11:44 am, edited 1 time in total.
rko
User
User
Posts: 21
Joined: Thu Jul 17, 2008 1:44 pm
Location: germany

CryptoSys API

Post by rko »

hi,

thanx alot for the interface. i use CryptoSys all the time with the digital mars d compiler as well as the CryptoSys KeyExchange library.
the libs are really fast and stable.

rko javascript:emoticon(':D')
Post Reply