a little help needed. I have a method that generates a otpauth string to be used with Google Authenticator
CkCrypt2 crypt;
CkString encodedString;
CkByteData inputData;
inputData.append2(secretKey.c_str(), secretKey.length());
bool success = crypt.Encode(inputData, "base32", encodedString);
stringstream uriStream;
uriStream << "otpauth://totp/" << username << "?secret=" << encodedString;
string uri = uriStream.str();
This then generates a QR code image, all seems fine at this point.
I then have a method to verify the OTP supplied by the user to a system generated OTP
CkCrypt2 crypt;
string origSecretKey; //this gets set earlier in the method by retrieving it from the database
const char* otp = crypt.totp(origSecretKey.c_str(), "base32", "0", "", 30, 6, -1, "sha1");
cstring strOtp(otp);
bool success = (m_twoFactorCode == strOtp);
No matter what happens, the 6-digit OTPs never match. Any help very much appreciated.
Here is how I generate the QR code
BOOL CUserAdminGrid::GenerateQRCode(const std::string& text, int size, int scale, const std::string& filename) {
QRcode* qrcode = QRcode_encodeString(text.c_str(), 0, QR_ECLEVEL_L, QR_MODE_8, 1);
if (qrcode) {
int qrSize = qrcode->width;
int newQrSize = qrSize * scale;
FILE* fp = fopen(filename.c_str(), "wb");
if (fp) {
png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
png_infop info_ptr = png_create_info_struct(png_ptr);
png_init_io(png_ptr, fp);
png_set_IHDR(png_ptr, info_ptr, newQrSize, newQrSize, 8, PNG_COLOR_TYPE_RGB_ALPHA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_write_info(png_ptr, info_ptr);
png_bytep row = new png_byte[newQrSize * 4];
for (int y = 0; y < newQrSize; ++y) {
int qy = y / scale;
png_bytep p = row;
for (int x = 0; x < newQrSize; ++x) {
int qx = x / scale;
int module = (qrcode->data[qy * qrSize + qx] & 0x1) ? 0 : 255;
*p++ = 255; // Red
*p++ = 255; // Green
*p++ = 255; // Blue
*p++ = module; // Alpha
}
png_write_row(png_ptr, row);
}
png_write_end(png_ptr, info_ptr);
delete[] row;
fclose(fp);
png_free_data(png_ptr, info_ptr, PNG_FREE_ALL, -1);
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
}
QRcode_free(qrcode);
return true;
}
else
{
return false;
}
}