某个代码,由于是逆向而来的,没有正确的rsa计算表示方式。程序在32位下时运行正常,但是在64位下则不正常,百思不得其解。
后来用hex/bin大法解决了,具体参见下面的代码。通过比较得到,32/64下BN结构 中的数据区的表示地址刚好相反,有点类似主机/网络字节顺的问题,也就是大端小端问题。但是同一台机器下,只是32、64位的差异,却有如此的不一样,比较困惑。
int rsa_decrypt_new(unsigned char* szInput, int nInLen, unsigned char* szOutput)
{
// test only
size_t nOutLen = 0;
if (!szInput || !szOutput)
{
return 0;
}
//rsa= RSA_generate_key(512, RSA_F4, NULL, NULL);
BIGNUM* a, * p, * ret, * m;
BN_CTX* ctx = NULL;
if ((ctx = BN_CTX_new()) == NULL)
return NULL;
BN_CTX_start(ctx);
ret = BN_new();
a = BN_new();
p = BN_new();
m = BN_new();
//a->dmax = 64 / sizeof(BN_ULONG);
//m->dmax = 64 / sizeof(BN_ULONG);
//p->dmax = 64 / sizeof(BN_ULONG);
//a->top = 64 / sizeof(BN_ULONG);
//p->top = 64 / sizeof(BN_ULONG);
//m->top = 64 / sizeof(BN_ULONG);
//a->d = (BN_ULONG*)szInput; //a
//m->d = (BN_ULONG*)key1; // m
//p->d = (BN_ULONG*)key2; // p
/*
这里的合理做法当然是64/sizeof(BN_ULONG)
dmax的意思是,d的长度,以BN_ULONG为单位
数据的长度是512个bit,也即16个32字节,如果是32bit的话,那么就是16个BN_ULONG。但如果是64bit,那么就是8个BN_ULONG。
*/
const char* szM = "DB972452587D56DE5648C412807B314F4F5608B70A748E8DADF1DA680C452EE19750E414F6D52925C38B12255E315A8934FF0CA86CD90B41CE22073DD87C4391";
const char* szP = "C500DB59D2D246D7CC954CEFC52D527E7591BC42E6009763CC6ED89746C5185BE3FD2FE9BE087AAF4FE1B56869EC889AA91244F526A5B0CE0E5A16A817FF84F3";
//const char* szA = "D85DF038986C00C60B9FF3951470097C851B900AE0A24A5BFDC212977CD8A6996F5CE9E71FB88DA9F96972F03A3ABE951B6226BFE2F63C4D40F1F57FB97F6AED";
unsigned char szBufA[129] = { 0 };
const char* szBNA = BN_bn2hex(a);
int nLenM = BN_hex2bn(&m, szM);
int nLenP = BN_hex2bn(&p, szP);
bin2str(szBufA, szInput, nInLen);
int nLenA = BN_hex2bn(&a,(const char*)szBufA);
unsigned char szBinA[65] = { 0 };
int binALen = BN_bn2bin(a, szBinA);
// 计算a的p次方,再模m,值储存在r中。返回1或者0 BN_mod_exp (r, a, p, m, ctx);
//-------------
if (!BN_mod_exp(ret, a, p, m, ctx))
{
goto _Exit;
}
nOutLen = ret->d[0];
::memcpy(szOutput, (void*)&(ret->d[1]), nOutLen);
_Exit:
BN_clear_free(ret);
a->d = NULL;
p->d = NULL;
m->d = NULL;
BN_clear_free(a);
BN_clear_free(p);
BN_clear_free(m);
BN_CTX_free(ctx);
return (int)nOutLen;
}