我有RSA加密我的字符串,但它现在是一个unsigned char *。如何创建可以为用户输出的人类可读的std :: string?我想在亚马逊签名的网址中使用它。以下是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填充。此函数不处理PKCS#1中指定的algorithmIdentifier。 生成或验证PKCS#1签名时,应使用RSA_sign(3)和RSA_verify(3)。
答案 0 :(得分:1)
首先,将它放入std::string
对象中,这通常可能会有所帮助:
std::string s{private_key, size};
但是,为了使其与Amazon的方案兼容,您需要挑选(或编写自己的)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]};
答案 1 :(得分:1)
要保存所有数据,请使用此std :: string构造函数:std :: string(char * data,int size)。由于输出MIGHT包含空字符,因此大小将很有用。
要通过网址将其发送到亚马逊,请再次考虑使用base64编码,因为加密数据可能包含NULL和其他恶作剧。