000
13.10.2019, 05:22 Uhr
Merkaber
|
Hallo liebe Forengemeinde. Dies ist mein erster Eintrag hier, da mein Post auf Stackoverflow noch keine Antwort erhalten hat. Seid 5 Tagen sitze ich nun an einem Problem, welches sich mit meinen bisherigen C++ Kenntnissen nicht loesen laesst.
Was moechte ich erreichen: Ich moechte eine OAuth 2.0 Authentifikation mit einem Server in C++ implementieren um GET requests, die einen Authentifikations Token benoetigen, senden zu koennen. Die Daten werden dann fuer meine GTK+ Anwendung verwendet. Hierbei wird das PKCE Protocol verwendet. Es handelt sich um eine Swagger API fuer das MMORPG EVE-Online. Natuerlich gibt es ein Beispiel fuer eine native desktop Anwendung auf Github fuer eben jenes interface, jedoch in Python.
Grundlegend versuche ich nun also seid Tagen diesen Python code in C++ zu schreiben, was aber nicht funktionieren will. Ich habe auch schon versucht die bytes vom Python Beispiel in meinen C++ code zu uebertragen um zu schauen woran es liegt. Mein Verdacht liegt beim Sha256.
Hier erstmal der Python code, bei dem es in C++ hakt:
Python: |
import base64 import hashlib import secrets
#Generate code challenge random = base64.urlsafe_b64encode(secrets.token_bytes(32)) m = hashlib.sha256() m.update(random) d = m.digest() code_challenge = base64.urlsafe_b64encode(d).decode().replace("=", "")
...
code_verifier = base64.urlsafe_b64encode(random).decode().replace("=", "")
|
Nun mein Versuch in C++:
C++: |
void SSOAuthentication::generateCodeChallenge() { // Generate PKCE_BYTE_NUM of random bytes std::random_device randomDevice; unsigned char randomBuffer[PKCE_BYTE_NUM]; for (unsigned char& i : randomBuffer) { i = randomDevice(); }
// Encode the raw random bytes to base64-url-safe std::string randomEncodedTmp = Base64::base64EncodeUrlSafe(randomBuffer, PKCE_BYTE_NUM);
// Save the encoded random bytes random = (unsigned char*) randomEncodedTmp.c_str();
// Hash the given code challenge with sha256 std::string hashedTmp = sha256(randomEncodedTmp); auto unsignedHashedTmp = (unsigned char*) hashedTmp.c_str();
// Encode hashed code challenge std::string encodedHashedTmp = Base64::base64EncodeUrlSafe(unsignedHashedTmp, hashedTmp.length());
// Replace all occurrences of '=' with '' encodedHashedTmp.erase(std::remove(encodedHashedTmp .begin(), encodedHashedTmp .end(), '='), encodedHashedTmp .end());
// Save the hashed code challenge hashedCodeChallenge = (unsigned char*) encodedHashedTmp.c_str();
// Encode random again std::string encodedRandomTmp = Base64::base64EncodeUrlSafe(random, randomEncodedTmp.length());
// Replace all occurrences of '=' with '' encodedRandomTmp.erase(std::remove(encodedRandomTmp.begin(), encodedRandomTmp.end(), '='), encodedRandomTmp.end());
// Save the code verifier codeVerifier = (unsigned char*) encodedRandomTmp.c_str(); }
|
Fuer das Base64 encoding nutze ich folgende Antwort von Stackoverflow: Antwort von LihO
Fuer Sha256 benutze ich folgendes Tutorial: Sha256
Da ich es auch nicht geschafft habe die random generierten Bytes als bitstring in C++ zu uebetragen und dann zu kodieren, um zu schauen, ob die mit Python uebereinstimmen, weiss ich nicht wie ich nun vorgehen kann, um irgendwie mein Ziel zu erreichen oder zu schauen, woran es liegt.
Python: |
import base64 import hashlib import secrets import sys
def main(): # Generate 32 random bytes and print them random_bytes = secrets.token_bytes(32)
i = int.from_bytes(random_bytes, byteorder=sys.byteorder) binRep = bin(i) print("binary representation: \n{}\ncount: {}\n".format(binRep, sys.getsizeof(random_bytes)))
encoded_random_bytes = base64.urlsafe_b64encode(random_bytes) print("random bytes: {}\nbase 64 encoded: {}\nnumber of bytes (encoded): {}\n".format(random_bytes, encoded_random_bytes, sys.getsizeof(encoded_random_bytes)))
main()
|
C++: |
static unsigned char* convertToUnsignedChar(const std::string &string);
int main() {
std::string pythonRandomBytes = "10101000 00010110 10100000 0010110001000000101010001010100101100001110011000001111111" "1101101100000111101101101010100000000011001010101000110000001000000111111011110101" "1111111101110110110101110010001001101000100101001111011001001100001000111001101111" "1001010101";
std::stringstream sstream(pythonRandomBytes); std::string output; while(sstream.good()) { std::bitset<8> bits; sstream >> bits; unsigned long c = bits.to_ulong(); unsigned char cc = static_cast<unsigned char>(c); output += cc; }
std::cout << "Entered python random bytes..." << std::endl; std::cout << (unsigned char*) output.c_str() << std::endl; std::cout << "Entered random bytes count: " << std::to_string(output.length()) << std::endl;
std::cout << "starting encoding..." << std::endl;
// Get the length of the random bytes unsigned int randomBytesLength = static_cast<unsigned int>(output.length());
// Convert to unsigned char* unsigned char* pythonRandomBytesUnsigned = convertToUnsignedChar(output);
// Encode string std::string encodedPythonRandomBytes = Base64::base64EncodeUrlSafe(pythonRandomBytesUnsigned, randomBytesLength);
std::cout << "encoded: " << encodedPythonRandomBytes << std::endl; std::cout << "length of string: " << encodedPythonRandomBytes.length() << std::endl;
return 0; }
static unsigned char* convertToUnsignedChar(const std::string &string) { std::vector<unsigned char> vec = std::vector<unsigned char>(string.data(), string.data() + string.length() + 1);
return &vec[0]; }
|
Dies sollte nur eine Moeglichkeit des debuggings sein, die ich versucht habe.
Nochmal mein komplettes Projekt: Github
Vielen Dank fuer eure Hilfe! Dieser Post wurde am 13.10.2019 um 05:22 Uhr von Merkaber editiert. |