我写了一个web服务,服务器用php编写,客户端用c ++编写,我使用openssl包生成rsa对密钥以保证数据传输。 在第一次我写了两个客户端服务器在PHP准备服务,一切顺利。但是当我开始将客户端php代码转移到c ++中时,我遇到了openssl方法的问题。 最大的问题是签名数据在php和c ++代码中都不匹配。 我获取md5数据并使用openssl_sign方法签署md5数据,然后在明文数据的末尾附加符号并发送到客户端(过去已为客户端发送公钥)。在客户端我再次做了这个进步。但标志不能正确验证。
may program有什么问题?
请帮助,谢谢。
php side(webservice)代码:
function sign($cleartext)
$msg_hash = md5($cleartext);
$sig = "";
$ok = openssl_sign($msg_hash, $sig, $this->private_key);
if ($ok == 1)
{
$signed_data = $cleartext . "----SIGNATURE:----" . base64_encode($sig);
//$signed_data = $this->encryptAES($signed_data, $this->password);
return base64_encode(mysql_real_escape_string($signed_data));
}
elseif ($ok == 0)
{
$eroor = "bad";
return base64_encode($eroor);
}
else
{
$eroor = "ugly, error checking signature";
return base64_encode($eroor);
}
}
和C ++方(客户端)代码:
int Crypto::rsaVerify(string msgStr, const char *pk) {
int length;
char *pkStr = new char[this->publicKey.length() + 1];
strcpy_s(pkStr, this->publicKey.length()+1,this->publicKey.c_str());
this->setPubKey((unsigned char *)pkStr,strlen(pkStr));
// Find and Splite Data
size_t current = 0;
string delimiters = "----SIGNATURE:----";
size_t next = msgStr.find( delimiters, current );
string dataStr = msgStr.substr( current, next - current );
char *msg = new char[dataStr.length() + 1];
strcpy_s(msg, dataStr.length()+1,dataStr.c_str());
// Find and Split sign
string signData = msgStr.substr(next + delimiters.length(), msgStr.length());
Coding *codingObj = new Coding();
signData = codingObj->base64_decode(signData);
char *signBuf = new char[signData.length() + 1];
strcpy_s(signBuf, signData.length()+1, signData.c_str());
unsigned char *dataMD5 = new unsigned char [MD5_DIGEST_LENGTH];
MD5((const unsigned char *)msg,strlen(msg),dataMD5);
char md5String[MD5_DIGEST_LENGTH + 1];
AsciiString2HexString(dataMD5,(unsigned char *)md5String, MD5_DIGEST_LENGTH);
md5String[MD5_DIGEST_LENGTH] = '\0';
char md5String1[MD5_DIGEST_LENGTH + 1];
AsciiString2HexString((unsigned char *)md5String1,(unsigned char *)md5String1, MD5_DIGEST_LENGTH);
md5String1[MD5_DIGEST_LENGTH] = '\0';
unsigned char * key2;
getPubKey(&key2);
unsigned int signLen = 256;//strlen(md5String);
char errorBuffer[120];
unsigned char message_digest[SHA_DIGEST_LENGTH];
SHA1((const unsigned char *)md5String1, strlen(md5String1), message_digest);
if(RSA_verify(NID_sha1,(const unsigned char *)message_digest, SHA_DIGEST_LENGTH,(const unsigned char *)signBuf,signLen,this->keyPair))
{
return 1;
}
else
{
ERR_error_string(ERR_get_error(), errorBuffer);
}
if(RSA_verify(NID_sha1,(const unsigned char *)md5String1, strlen(md5String1),(const unsigned char *)signBuf,signLen,this->keyPair))
{
return 1;
}
else
{
ERR_error_string(ERR_get_error(), errorBuffer);
}
if(RSA_verify(NID_sha1,(const unsigned char *)md5String, strlen(md5String),(const unsigned char *)signBuf,signLen,this->keyPair))
{
return 1;
}
else
{
ERR_error_string(ERR_get_error(), errorBuffer);
}
if(RSA_verify(NID_sha1,(const unsigned char *)dataMD5, strlen((char *)dataMD5),(const unsigned char *)signBuf,signLen,this->keyPair))
{
return 1;
}
else
{
ERR_error_string(ERR_get_error(), errorBuffer);
}
return 0;
}
int Crypto::getPriKey(unsigned char **priKey) {
BIO *bio = BIO_new(BIO_s_mem());
PEM_write_bio_RSAPrivateKey(bio, this->keyPair, NULL, NULL, NULL, NULL, NULL);
int priKeyLen = BIO_pending(bio);
*priKey = (unsigned char*)malloc(priKeyLen);
if(priKey == NULL) return FAILURE;
BIO_read(bio, *priKey, priKeyLen);
// Insert the NUL terminator
(*priKey)[priKeyLen-1] = '\0';
BIO_free_all(bio);
return priKeyLen;
}
答案 0 :(得分:1)
也许是因为openssl_sign需要数据作为第一个参数而不是数据的哈希值。默认情况下,此函数使用OPENSSL_ALGO_SHA1包含散列。
并且,如果可以的话,优先选择SHA2,256位以上。不建议将MD5和SHA1用于新项目...