2015-06-17 8 views
6

मैं काफी नौसिखिया सी ++ प्रोग्रामर हूं (मैं अभी भी कॉलेज में हूं इसलिए मुझे लगता है कि मैं सामान्य रूप से काफी नौसिखिया प्रोग्रामर हूं) और मैं एक उत्पन्न करने की कोशिश कर रहा हूं सी ++ में जेडब्ल्यूटी। मैं हेडर और पेलोड को जेनरेट और एन्कोड करने में सक्षम हूं, लेकिन जब मैं इसे jwt.io पर देखता हूं तो openssl की hmac लाइब्रेरी का उपयोग करके उत्पन्न हस्ताक्षर अमान्य प्रतीत होता है। मुझे लगता है कि यह कुछ गड़बड़ गलती के कारण है जिसे मैं नहीं देख रहा हूं। यदि आप मेरी बग पा सकते हैं तो मैं इसकी सराहना करता हूं। यदि आपके पास सामान्य रूप से मेरे कोड को बेहतर बनाने के सुझाव भी हैं, तो इसकी भी सराहना की जाएगी। नोट मुझे जेएसएस के लिए openssl और बढ़ावा देना है।सीडब्ल्यू + में जेडब्ल्यूटी (जेएसओएन वेब टोकन) बूस्ट और ओपनएसएल बग का उपयोग कर

**** अद्यतन ****

मुझे लगता है कि अतिरिक्त नई लाइनों जोड़ा जा रहा था की खोज की और इस प्रमाणीकरण के दौरान त्रुटियों का कारण बना। वर्तमान में मैं str.erase बोल रहा हूँ उन्हें हटाने के लिए, लेकिन अगर किसी को दे सकता है मुझे पता है, जहां वे आ रहे हैं मैं इसे सराहना करते हैं तो मैं स्ट्रिंग


char* Auth::genJWT() 
{ 
    ptree pt; 
    std::stringstream jwt; 

    //Make and encode header 
    pt.put("typ","JWT"); 
    pt.put("alg","HS256"); 
    std::ostringstream buf; 
    write_json(buf, pt, false); 
    std::string header = buf.str(); 
    jwt << base64_encode((unsigned char*)header.c_str(), (int) header.length()); 

    //clear buffer 
    pt.clear(); 
    buf.clear(); 
    buf.str(""); 

    //make pay load 
    pt.put("org_guid", Config::organization_guid); 
    pt.put("agent_guid", Config::agent_guid); 
    write_json(buf, pt, false); 
    std::string payload = buf.str(); 
    jwt << '.' << base64_encode((unsigned char*)payload.c_str(), (int) payload.length()); 

    //sign data 
    std::string signed_data = signToken(jwt.str()); 
    jwt << '.' << base64_encode((unsigned char*) signed_data.c_str(), (int) signed_data.length()); 

    //jwt made 
    std::cout << "JWT Token: " << jwt.str() << std::endl; 

    //Note I am testing by copying the token into an online debugger 
    //returning "" is not my bug 
    return ""; 
} 

हेरफेर करने के लिए इस विधि का उपयोग मैं है होने से बचने कर सकते हैं हस्ताक्षर टोकन

std::string Auth::signToken(std::string to_sign) 
{ 
    //std::string key = Config::secret; 
    std::string key = "foo"; 

    unsigned int len = 32; 
    unsigned char signed_data[32]; 

    HMAC_CTX ctx; 
    HMAC_CTX_init(&ctx); 

    HMAC_Init_ex(&ctx, &key[0], (int) key.length(), EVP_sha256(), NULL); 
    HMAC_Update(&ctx, (unsigned char*)&to_sign[0], to_sign.length()); 
    HMAC_Final(&ctx, signed_data, &len); 
    HMAC_CTX_cleanup(&ctx); 

    std::stringstream ss; 
    ss << std::setfill('0'); 

    for(unsigned int i = 0; i < len; i++) 
    { 
     ss << signed_data[i]; 
    } 

    return (ss.str()); 
} 

यह मैं कैसे base64Url

में डेटा सांकेतिक शब्दों में बदलना
std::string Auth::base64_encode(const unsigned char* input, int length) 
{ 
    BIO *bmem, *b64; 
    BUF_MEM *bptr; 

    b64 = BIO_new(BIO_f_base64()); 
    bmem = BIO_new(BIO_s_mem()); 
    b64 = BIO_push(b64, bmem); 
    BIO_write(b64, input, length); 
    BIO_flush(b64); 
    BIO_get_mem_ptr(b64, &bptr); 

    std::stringstream ss; 

    //make URL safe 
    for(unsigned int i = 0; i < bptr->length - 1; i++) 
    { 
     switch(bptr->data[i]) 
     { 
      case '+': 
       ss << '_'; 
       break; 
      case '/': 
       ss << '-'; 
       break; 
      case '=': 
       //don't add in padding 
       break; 
      default: 
       ss << bptr->data[i]; 
       break; 
     } 
    } 

    BIO_free_all(b64); 
    return (ss.str()); 
} 

उत्तर

4

OpenSSL है मैं प्रत्येक 64'th चरित्र के बाद एक नई पंक्ति चरित्र nserts, आप का उपयोग करके यह निष्क्रिय कर सकते हैं:

BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 

यहाँ the documentation देखें।

1) आप बफर का अंतिम वर्ण को छोड़ जब यह यूआरएल-सुरक्षित बनाने:

अपने कोड का परीक्षण जब मैं भी निम्न 2 समस्या नहीं पाई गई। आप को दूर करना चाहिए - '-' और '/' से '_' 1.

for(unsigned int i = 0; i < bptr->length ; i++) 

2) जब Base64 उत्पादन यूआरएल-सुरक्षित बनाने आप के साथ बदलने के लिए '+' की जरूरत है। आपके कोड के आसपास दूसरी तरफ था। तो:

case '+': 
    ss << '-'; 
    break; 
case '/': 
    ss << '_'; 
    break; 
संबंधित मुद्दे