2015-08-25 69 views
1

我有RSA加密我的字符串,但它現在是一個無符號字符*獲得人類可讀的std :: string。如何創建一個我可以爲用戶輸出的人類可讀的std :: string?我想在亞馬遜簽名的網址中使用它。以下是GitHub如何從RSA_private_encrypt

unsigned char* RSA_SHA1_Sign(std::string policy, RSA *privateKey) throw(std::runtime_error) 
{ 

    //sha1 digest the data 
    unsigned char hash[SHA_DIGEST_LENGTH] = {'0'}; 
    SHA1((const unsigned char *)policy.c_str(), policy.length(), hash); 

    // Sign the data 
    int rsaSize = RSA_size(privateKey); 
// std::unique_ptr<unsigned char[]> signedData(new unsigned char[size]);//if c++11 available 
unsigned char *signedData = (unsigned char *)malloc(sizeof(unsigned char) * rsaSize); 
    unsigned int signedSize = 0; 

    //use RSA_sign instead of RSA_private_encrypt 
    if(!RSA_sign(NID_sha1, hash, SHA_DIGEST_LENGTH, signedData, &signedSize, privateKey)){ 
     throw std::runtime_error("Failed to sign"); 
    } 

    return signedData; 
} 

std::string base64Encode(unsigned char *signedData) 
{ 
    //prepare 
    BIO *b64 = BIO_new(BIO_f_base64()); 
    BIO *bmem = BIO_new(BIO_s_mem()); 
    BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); 
    b64 = BIO_push(b64, bmem); 

    //write 
    BIO_write(b64, signedData, 256); 
    BIO_flush(b64); 


    //create string 
    BUF_MEM *bptr; 
    BIO_get_mem_ptr(b64, &bptr); 
    std::string base64String(bptr->data); 

    BIO_free_all(b64); 
    return base64String; 
} 
int main(int argc, const char * argv[]) { 

    RSA *privateKey = createRSAFromPrivateKeyFile("/path/to/privatekey"); 
    std::string sourceString = "testing"; 
    std::string signature = RSA_SHA1_Sign(sourceString, privateKey); 
    std::string encodedSignature = base64Encode(signature); 
    std::cout << "RESULT: " << encodedSignature << std::endl; 

    return 0; 
} 

UPDATE肉和代碼的土豆:我是使用了錯誤的標誌功能。一旦更新,使用base64編碼給了我正確的字符串。

RSA_PKCS1_PADDING PKCS#1 v1.5填充。此函數不處理PKCS#1中指定的algorithmIdentifier。 生成或驗證PKCS#1簽名時,應使用RSA_sign(3)和RSA_verify(3)。

+1

只需使用std :: string構造函數:std :: string(char \ * data,int size):-)由於輸出MIGHT包含* null *字符,因此大小將很有用。 – Xabre

+3

std :: string將愉快地存儲完全不可讀的數據。考慮改寫你的問題來說明你是否特別需要一個人類可讀的字符串,如果是的話,是什麼格式,或者如果你只是想發出原始密鑰字節。 – Olipro

+1

'malloc'?在我們C++的時刻? –

回答

1

要保存所有的數據,使用該的std :: string構造函數:的std :: string(CHAR *數據,int大小)。由於輸出MIGHT包含空字符,因此大小將會很有用。

要通過url將其發送到amazon,請考慮再次使用base64編碼,因爲加密數據可能包含NULL和其他shenanig。

1

首先,把它變成一個std::string對象,這可能會在一般的幫助:

std::string s{private_key, size};

然而,隨後選擇與亞馬遜的方案不兼容,你需要挑選出(或者編寫你自己的)Base64庫和URL編碼器來轉義特殊的URL字符。粗略搜索Google或StackOverflow將爲您提供您在這方面需要的內容,並且寫出如何在C++中執行Base64編碼和URL轉義,這超出了本問題的範圍。

而且,由於你使用C++,考慮std::unique_ptr<unsigned char[]>而不是直線上升malloc();

std::unique_ptr<unsigned char[]> signedData{new unsigned char[size]};

+0

的確,使用*的unique_ptr * ......如果他的編譯器支持C++ 11 ... :-) – Xabre

+0

問題專門詢問了*人類可讀*字符串。 –

+0

它沒有,當我寫它。將在任何情況下調整 – Olipro