2010-04-01 102 views
4

我使用openssl BIO對象將二進制字符串轉換爲base64字符串。代碼如下:openssl加密庫 - base64轉換

void ToBase64(std::string & s_in) { 
    BIO * b_s = BIO_new(BIO_s_mem()); 
    BIO * b64_f = BIO_new(BIO_f_base64()); 

    b_s = BIO_push(b64_f , b_s); 

    std::cout << "IN::" << s_in.length(); 
    BIO_write(b_s, s_in.c_str(), s_in.length()); 


    char * pp; 
    int sz = BIO_get_mem_data(b_s, &pp); 

    std::cout << "OUT::" << sz << endl; 

    s_in.assign(pp,sz); 
    //std::cout << sz << " " << std::string(pp,sz) << std::endl; 

    BIO_free (b64_f); // TODO ret error potential 
    BIO_free (b_s); // 
    } 

的在長度64或72。然而輸出總是65,這是不正確它應當比大得多。該文檔不是世界上最好的,AFAIK bio_s_mem對象應該是動態增長的。我究竟做錯了什麼 ?

我可能更適合找到一個自包含的C++類,它不提供流支持,並且支持base64轉換。流式支持不適合我的應用程序。但是我只是想堅持使用openSSL,因爲我已經準備好了,這取決於一些加密程序。無論如何,我會在分析後做出這樣的決定。

回答

2

你有兩個問題:

  • 你需要調用BIO_get_mem_data()在MEM生物 - 但你已經失去了對它的引用(你從BIO_push的返回值,這等於b64_f覆蓋它)。
  • 在向所有數據寫入數據後,您應該在base64 bio上調用BIO_flush()
+0

謝謝你,這兩點非常清楚了(我懷疑沖洗就可以了)。爲了響應覆蓋問題:我複製了以下示例中的push操作:http://www.openssl.org/docs/crypto/BIO_f_base64.html#推送應用到的目標生物對象被覆蓋。 – 2010-04-01 12:41:50

+0

是的,沖洗的確確實實在在,對潛在的手柄泄漏有任何想法?我認爲第一點是沒有意義的。 – 2010-04-01 12:50:46

+0

那麼在那個例子中,沒關係的是,他們失去了對fp bio的引用,因爲他們永遠不需要直接訪問它 - 它的輸出會轉到文件。另一方面,你需要明確地從mem生物中提取輸出。我懷疑它可能只是「偶然」工作,因爲'BIO_get_mem_data()'在Base64生物體上工作(也許它是建立在下面的一個mem生物體上的)?如果你通過它推動更多的數據,它可能會停止工作。 – caf 2010-04-01 12:56:53

0

我想你想要做的是改變參數的順序爲BIO_push。

B_S = BIO_push(B_S,b64_f)

+0

謝謝你的迴應。推送是在管道中放置一個過濾器,openSSL文檔中的示例顯示了這一點:http://www.openssl.org/docs/crypto/BIO_f_base64.html#。因此,我的功能順序是正確的。 – 2010-04-01 12:52:12

+0

有趣。根據BIO_push頁面http://www.openssl.org/docs/crypto/BIO_push.html,BIO_push調用返回第一個參數並附加第二個參數。這將有base64示例覆蓋(並丟失)fp。其中一頁必須是錯誤的。 – Fred 2010-04-02 04:08:57