如何从 RSA_private_encrypt 获得人类可读的 std::string
How to get human readable std::string from RSA_private_encrypt
我用 RSA 加密了我的字符串,但它现在是一个 unsigned char *。如何创建可以为用户输出的人类可读 std::string?我想在亚马逊签名 url 中使用它。这是来自 GitHub
的代码的主要内容
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;
}
更新:我使用了错误的符号函数。更新后,使用 base64 编码给了我正确的字符串。
RSA_PKCS1_PADDING
PKCS #1 v1.5 padding. This function does not handle the algorithmIdentifier specified in PKCS #1.
When generating or verifying PKCS #1 signatures, RSA_sign(3) and RSA_verify(3) should be used.
首先,将它放入一个 std::string
对象中,这通常会有帮助:
std::string s{private_key, size};
但是,要使其与亚马逊的方案兼容,您需要选择(或编写自己的)Base64 库和 URL 编码器以转义特殊的 URL 字符。粗略搜索 Google 或 Whosebug 将为您提供这方面所需的内容,写出如何在 C++ 中进行 Base64 编码和 URL 转义超出了这个问题的范围。
此外,由于您使用的是 C++,请考虑 std::unique_ptr<unsigned char[]>
而不是直接 malloc();
std::unique_ptr<unsigned char[]> signedData{new unsigned char[size]};
要保存所有数据,请使用此 std::string 构造函数:std::string( char *data, int size )。该大小将很有用,因为输出可能包含空字符。
要通过 url 将其发送到亚马逊,再次考虑使用 base64 编码,因为加密数据可能包含 NULL 和其他恶作剧。
我用 RSA 加密了我的字符串,但它现在是一个 unsigned char *。如何创建可以为用户输出的人类可读 std::string?我想在亚马逊签名 url 中使用它。这是来自 GitHub
的代码的主要内容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;
}
更新:我使用了错误的符号函数。更新后,使用 base64 编码给了我正确的字符串。
RSA_PKCS1_PADDING PKCS #1 v1.5 padding. This function does not handle the algorithmIdentifier specified in PKCS #1. When generating or verifying PKCS #1 signatures, RSA_sign(3) and RSA_verify(3) should be used.
首先,将它放入一个 std::string
对象中,这通常会有帮助:
std::string s{private_key, size};
但是,要使其与亚马逊的方案兼容,您需要选择(或编写自己的)Base64 库和 URL 编码器以转义特殊的 URL 字符。粗略搜索 Google 或 Whosebug 将为您提供这方面所需的内容,写出如何在 C++ 中进行 Base64 编码和 URL 转义超出了这个问题的范围。
此外,由于您使用的是 C++,请考虑 std::unique_ptr<unsigned char[]>
而不是直接 malloc();
std::unique_ptr<unsigned char[]> signedData{new unsigned char[size]};
要保存所有数据,请使用此 std::string 构造函数:std::string( char *data, int size )。该大小将很有用,因为输出可能包含空字符。
要通过 url 将其发送到亚马逊,再次考虑使用 base64 编码,因为加密数据可能包含 NULL 和其他恶作剧。