RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Für allgemeine Fragen zur Programmierung mit PureBasic.
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von melow »

Hi Leute,
also ich hab nun Wochenlang alles abgescant. Alle Foren und den ganzen Google Index. Nix. Einfach nix.

Ich würd gern (besser gesagt: muss) die kryptographischen Funktionen von RSA und Diffie Hellman in PB benützen.
Am besten Cross-OS, also ohne DLL loading, sondern als "Pure-Purebasic" Code oder Lib.

Aber zur Not würd ich auch eine DLL benützen... klar.

Es gab ein paar Versuche und Code-Schnipsel bzgl. RSA, aber leider nicht praktisch anwendbar (viel zu langsam bei einen 1024bit RSA Key... ).

Bzgl. Diffie Hellman hab ich gar nichts gefunden.

Habs dann mit den DLL von openssl versucht. Bin gescheitert an die Header Datei(en) von openssl nach PB zu portieren.
Hab die DLL von Cryptlib versucht. Gescheitert aus den gleichen Grund.

OK... wollt dann die Algorypthmen von RSA und DH selbst schreiben in PB. So komplex sind die ja nicht.
Gescheitert an Big Integer Operationen... bräuchte dazu auch eine (schnelle) Lib oder DLL wo ich dann wieder am Problem der Header Dateien angelangt bin die ich nicht nach PB portieren konnte.

Kann mir von Euch jemand weiterhelfen? Am allerbesten mit funktionierende Code-Examples oder Tipps wie ich an mein Ziel näher komme, RSA und DH in PB anzuwenden.

SSL/TLS Netwerkverbindungen (Client/Server) bräucht ich auch noch. Auch nix gefunden. Aber RSA und DH wären erstmal am wichtigsten.

Danke allen.
lg Melow
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von NicTheQuick »

Bezüglich RSA habe ich gerade einen C++-Code gefunden, wenn dir das weiter hilft. Er scheint relativ einfach zu sein: RSA Implementation in C++
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Re: RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von melow »

Danke! Ich müsst aus den Source dann eine DLL bauen mit den entsprechenden Exports (gehen c++ DLL's in PB einzubinden? glaub schon, oder?), hoffen daß ich es diesmal dann schaffe die Header Dateien nach PB zu portieren... und wenn bis dahin alles geklapt hat... ja, das dürfte dann bzgl. RSA klappen.

Ist aufjendefall gemerkt. Danke nochmals.

Vieleicht noch jemand mit einen Tipp oder gar was fertiges/anwendbares in PB?

lg Melow
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Re: RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von melow »

Nur für's Protokoll: Hier eine RSA Implementierung in C: http://code.google.com/p/rsa-in-c/ ich glaub mit dieser ist es leichter eine DLL zu kompilieren und diese dann in PB zu laden und die Header's zu portieren...
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8838
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von NicTheQuick »

Man kann den Code ja ein bisschen umschreiben und das OOP darin entfernen, sodass es ganz normaler C-Code wird. Oder man übersetzt alles nach PB. Die BigInt-Klasse ist dabei allerdings das größte.
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Re: RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von melow »

Ja, das wär natürlich schmackhaft, alles nach PB umzuschreiben, als Lib... Aber da würd ich sicherlich Wochenlang dransitzen... genau... vor allem die BigInt würd lang dauern.

Da wird mir grad klar... eigentlich wäre eine BigInt DLL sogar schon genug für mich. Denn den Rest, also RSA und DH, würd ich damit dann gut allein schaffen.
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von Kukulkan »

Hallo,

wir nutzen Crypto++ (http://www.cryptopp.com/) zusammen mit PureBasic unter Windows, Linux und MacOS. Haben das halt überall einmal als Library compiliert (dll, so, dylib).

Damit machen wir heute RSA, AES256 und SHA sowie Zufallszahlen (was man halt so braucht). Kann ich nur wärmstens empfehlen. Der PB source muss dann nicht mehr weiter angepasst werden. Nur ein CompilerIf um je nach OS die richtige Library zu laden.

[EDIT]Kann das leider nicht veröffentlichen, da es Teil unserer kommerziellen Produkte ist :| Fragen beantworte ich aber gerne.[/EDIT]

Grüße,

Kukulkan
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Re: RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von melow »

Hallo Kukulkan
genau das hatte ich auch als Plan B vor, eben eine bestehende Lib/DLL zu verwenden.

Bei Openssl und Cryptolib bin ich aber wie gesagt gescheitert die entsprechenden Header Dateien nach PB zu portieren. War schwieriger als ich anfangs dachte.

Würde auch gerne Crypto++ benützen aber ich glaub da werd ich auch scheitern mit den Headern.

Deshalb meine Frage: Ist es Dir evntl. möglich eure portierten PB Header von Crypto++ zu posten inkl. ein kleines Code-Schnipsel wie ihr dann die RSA Funktionen von Crypto++ in PB anspricht... das würd mir super helfen.

lg Melow

EDIT: OK, Frage hat sich erledigt da ich gerade noch Dein EDIT gelesen habe... hatte es schon vermutet. Ist auch voll OK. Danke aber dennoch. Ich werd noch ein bischen abwarten, evntl. ergibt sich noch etwas, und dann falls ich Crypto++ benützen sollte bestimmt nochmal auf Dein Angebot mir ein paar Fragen zu beantworten zurückkommen... Danke für Dein Angebot aber aufjendenfall schonmal.
Benutzeravatar
Kukulkan
Beiträge: 1066
Registriert: 09.09.2004 07:07
Wohnort: Süddeutschland
Kontaktdaten:

Re: RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von Kukulkan »

Ok, ein bisschen pas kann ich posten. RSA ist nicht dabei weil wir da eine spezielle Lib für haben, aber das Prinzip ist auch dafür schnell umgesetzt:

Code: Alles auswählen

Global libCryptocName.s = ""
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
  Macro CrProtoType
    PrototypeC
  EndMacro
CompilerEndIf

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  Macro CrProtoType
    PrototypeC
  EndMacro
CompilerEndIf

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  Macro CrProtoType
    PrototypeC
  EndMacro
CompilerEndIf

; -------------------------------------
; INITIALIZE CRYPTO-API's
; -------------------------------------
#CC_ERROR_BUFFER = 512
#CC_NO_PADDING = 0
#CC_ZEROS_PADDING = 1
#CC_PKCS_PADDING = 2

#CC_STRING = 0
#CC_BYTES  = 1
#CC_FILE   = 2

;{ prototyping and opening cryptoc
  
CrProtoType  cc_EncryptFile(szAlg.sbStr, szInFile.sbStr, szHexKey.sbStr, *szOutFileOrResult, padScheme.i, szHexIVector.sbStr)
CrProtoType  cc_DecryptFile(szAlg.sbStr, szInFile.sbStr, szHexKey.sbStr, *szOutFileOrResult, padScheme.i, szHexIVector.sbStr)
CrProtoType  cc_EncryptBytes(szAlg.sbStr, *input, *inLen, szHexKey.sbStr, *szHexResult, padScheme.i, szHexIVector.sbStr)
CrProtoType  cc_DecryptBytes(szAlg.sbStr, *input, *inLen, szHexKey.sbStr, *szHexResult, padScheme.i, szHexIVector.sbStr)
CrProtoType  cc_EncryptString(szAlg.sbStr, szHextext.sbStr, szHexKey.sbStr, *szHexResult, padScheme.i, szHexIVector.sbStr)
CrProtoType  cc_DecryptString(szAlg.sbStr, szHextext.sbStr, szHexKey.sbStr, *szHexResult, padScheme.i, szHexIVector.sbStr)
CrProtoType  cc_GenerateRandomHex(byteLen.i, *szHexResult)
CrProtoType  cc_GetRemainderFromGEM(generator.sbStr, exponent.sbStr, modulus.sbStr, *szResult, *charLength);

CrProtoType  cc_HexHashInit(szAlg.sbStr, *ppHashCtx)
CrProtoType  cc_HexHashUpdate(*pHashCtx, *pBuf, len.i)
CrProtoType  cc_HexHashFinish(*pHashCtx, *szResult)
CrProtoType  cc_StringHexHash(szMessage.sbStr, szAlg.sbStr, *szResult)
CrProtoType  cc_MemoryHexHash(*pBuf, len.i, szAlg.sbStr, *szResult)
CrProtoType  cc_FileHexHash(*szFilename, szAlg.sbStr, *szResult)

CrProtoType cc_HexEncodeBytes(*input, len.i, *szResult)
CrProtoType cc_HexDecodeBytes(input.sbStr, *result)

CrProtoType cc_GenerateRSAKey(bitLen.i, *pubKey, *privKey, *charLength)
CrProtoType cc_RSAEncrypt(pubKey.sbStr, msg.sbStr, *cipher, *charLength)
CrProtoType cc_RSADecrypt(privKey.sbStr, cipher.sbStr, *msg, *charLength)
CrProtoType cc_RSASign(privKey.sbStr, msg.sbStr, *signature, *charLength)
CrProtoType cc_RSAVerify(pubKeyStr.sbStr, msg.sbStr, signature.sbStr, *errmsg, errLength)

Global cc_EncryptFile.cc_EncryptFile
Global cc_DecryptFile.cc_DecryptFile
Global cc_EncryptBytes.cc_EncryptBytes
Global cc_DecryptBytes.cc_DecryptBytes
Global cc_EncryptString.cc_EncryptString
Global cc_DecryptString.cc_DecryptString
Global cc_GenerateRandomHex.cc_GenerateRandomHex
Global cc_GetRemainderFromGEM.cc_GetRemainderFromGEM

Global cc_HexHashInit.cc_HexHashInit
Global cc_HexHashUpdate.cc_HexHashUpdate
Global cc_HexHashFinish.cc_HexHashFinish
Global cc_StringHexHash.cc_StringHexHash
Global cc_MemoryHexHash.cc_MemoryHexHash
Global cc_FileHexHash.cc_FileHexHash

Global cc_HexEncodeBytes.cc_HexEncodeBytes
Global cc_HexDecodeBytes.cc_HexDecodeBytes

Global cc_GenerateRSAKey.cc_GenerateRSAKey
Global cc_RSAEncrypt.cc_RSAEncrypt
Global cc_RSADecrypt.cc_RSADecrypt
Global cc_RSASign.cc_RSASign
Global cc_RSAVerify.cc_RSAVerify

;}

Global hCryptoc

Procedure.b __InitCryptoDLL()
  CompilerIf #PB_Compiler_OS = #PB_OS_Windows
    libCryptocName.s = "cryptoc.dll"
  CompilerEndIf
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
      libCryptocName.s = "x86_64/libcryptoc.so"
    CompilerElse
      libCryptocName.s = "/usr/lib/libcryptoc.so"
      If FileSize(libCryptocName.s) < 0
        libCryptocName.s = GetHomeDirectory() + "git/includes/third-party/libcryptoc.so" ; try development system location
        If FileSize(libCryptocName.s) < 0
          libCryptocName.s = "libcryptoc.so";  use default system path (last chance)
        EndIf
      EndIf
    CompilerEndIf
  CompilerEndIf
  
  CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
    libCryptocName.s = GetPathPart(ProgramFilename()) + "../System/Library/libcryptoc.dylib"
    If FileSize(libCryptocName.s) < 0
      libCryptocName.s = GetHomeDirectory() + "src/includes/third-party/libcryptoc.dylib" ; try development system location
      If FileSize(libCryptocName.s) < 0
        libCryptocName.s = "libcryptoc.dylib";  use default system path (last chance)
      EndIf
    EndIf
  CompilerEndIf
  hCryptoc = OpenLibrary(#PB_Any, libCryptocName.s)
  If hCryptoc <> 0
    cc_EncryptFile         = GetFunction(hCryptoc, "EncryptFile")
    cc_DecryptFile         = GetFunction(hCryptoc, "DecryptFile")
    cc_EncryptBytes        = GetFunction(hCryptoc, "EncryptBytes")
    cc_DecryptBytes        = GetFunction(hCryptoc, "DecryptBytes")
    cc_EncryptString       = GetFunction(hCryptoc, "EncryptString")
    cc_DecryptString       = GetFunction(hCryptoc, "DecryptString")
    cc_GenerateRandomHex   = GetFunction(hCryptoc, "GenerateRandomHex")
    cc_GetRemainderFromGEM = GetFunction(hCryptoc, "GetRemainderFromGEM")
    
    cc_HexHashInit        = GetFunction(hCryptoc, "HexHashInit")
    cc_HexHashUpdate      = GetFunction(hCryptoc, "HexHashUpdate")
    cc_HexHashFinish      = GetFunction(hCryptoc, "HexHashFinish")
    cc_StringHexHash      = GetFunction(hCryptoc, "StringHexHash")
    cc_MemoryHexHash      = GetFunction(hCryptoc, "MemoryHexHash")
    cc_FileHexHash        = GetFunction(hCryptoc, "FileHexHash")
    
    cc_HexEncodeBytes    = GetFunction(hCryptoc, "HexEncodeBytes")
    cc_HexDecodeBytes    = GetFunction(hCryptoc, "HexDecodeBytes")
    
    cc_GenerateRSAKey   = GetFunction(hCryptoc, "GenerateRSAKey")
    cc_RSAEncrypt       = GetFunction(hCryptoc, "RSAEncrypt")
    cc_RSADecrypt       = GetFunction(hCryptoc, "RSADecrypt")
    cc_RSASign          = GetFunction(hCryptoc, "RSASign")
    cc_RSAVerify        = GetFunction(hCryptoc, "RSAVerify")
    ProcedureReturn #True
  Else
    Debug "Can not find " + libCryptocName.s
    GlobalLog(#RF_LOG_CRIT, "Cant use " + libCryptocName.s + ". Please download the latest program-version and re-install.")
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.s GenerateRandomHEX(Bitlength.i, *resultCode)
  ; Generates a random key of Bitlength.i bits (double HEX-chars for the bytes)
  Shared hCryptoc
  If hCryptoc = 0
    __InitCryptoDLL()
  EndIf
  
  Protected Bytes.i, keys.s, r.i
  If Bitlength.i < 0 Or Bitlength.i > (1024*16)
    GlobalLog(#RF_LOG_CRIT, "Unsupported bitlength: '" + Str(Bitlength.i) + "'")
    PokeI(*resultCode, #RFEC_INVALID_PARAMETER)
    ProcedureReturn ""
  EndIf
  If (Bitlength.i % 8) <> 0 
    GlobalLog(#RF_LOG_CRIT, "Unsupported bitlength must be divisible by 8: '" + Str(Bitlength.i) + "'")
    PokeI(*resultCode, #RFEC_INVALID_PARAMETER)
    ProcedureReturn ""
  EndIf
  Bytes.i = Bitlength.i / 8
  keys.s = Space((Bytes.i * 2) + 1) ; for null termination
  r.i = cc_GenerateRandomHex(Bytes.i, @keys) 
  Protected wKeys.s = PeekS(@keys, -1, #PB_UTF8)
  wKeys = Trim(wKeys)
  If r <> 0
    GlobalLog(#RF_LOG_CRIT, "cc_GenerateRandomHex error code: " + GetErrorCodeMessage(r) + " [" + wKeys + "]")
    PokeI(*resultCode, r)
    ProcedureReturn ""
  EndIf
  
  PokeI(*resultCode, #RFEC_OK)
  ProcedureReturn wKeys
EndProcedure
Sollte ein guter Start sein.

Grüße,

Kukulkan
Zuletzt geändert von Kukulkan am 19.04.2013 18:12, insgesamt 1-mal geändert.
melow
Beiträge: 32
Registriert: 04.02.2006 05:05
Wohnort: Thailand

Re: RSA und Diffie Hellman ... ich bin kurz vorm Aufgeben

Beitrag von melow »

Kukulkan...Ja, das ist auch ein guter Start. Danke für's Posten.
Antworten