使用openssl在php中签名文件,并在c ++中验证 [英] sign a file with openssl in php and verify in c++

查看:223
本文介绍了使用openssl在php中签名文件,并在c ++中验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我写了一个webservice,服务器是用php写的,客户端用c ++编写,我用openssl包生成rsa对密钥来保护数据传输。
在第一次,我写了两个客户端在php服务器准备服务,一切都顺利。但是当我开始将客户端PHP代码转换为C ++我面临openssl方法的问题。
最大的问题是在php和c ++代码中签名的数据不匹配。
我获得md5的数据,并使用openssl_sign方法签署md5数据,然后在普通数据结尾附加符号并发送到客户端(过去的公钥已经发送给客户端)。在客户端我做了这个进展了。

I wrote a webservice that server is written in php and client is written in c++, and I used openssl package for generating rsa pair key to secure data transferming. At the first I wrote both client an server in php for preparing services and every things goes OK. but when I started transfer client php code into c++ I face into problems with openssl methods. The big problem is that the signed data does not match in both php and c++ codes. I get md5 of data and use openssl_sign method for signing md5 data and then append the sign at the end of plain data and send to client (In the past public key have been sent for client). in the client I did this progress again. but the sign dos not verify correctly.

请帮助,谢谢。

php侧(网络服务)代码:

php side (webservice) code:

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 ++端>

and C++ side (client) Code:

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;
}


推荐答案

也许因为openssl_sign需要数据第一个参数而不是数据的哈希。默认情况下,该函数使用OPENSSL_ALGO_SHA1来计算哈希值。

Maybe because openssl_sign need data as first argument and not the hash of data. By default, the hash is caclulated by this function with OPENSSL_ALGO_SHA1.

如果可以的话,preference SHA2,256bits等。不推荐对新项目使用MD5和SHA1 ...

And, if you can, prefere SHA2, 256bits and more. MD5 and SHA1 are not recommended for new projects...

这篇关于使用openssl在php中签名文件,并在c ++中验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆