首页
社区
课程
招聘
[求助]这个RSA函数如何还原成openssl的函数?或者还原成标准的c代码也可以.
发表于: 2016-1-3 17:39 4960

[求助]这个RSA函数如何还原成openssl的函数?或者还原成标准的c代码也可以.

2016-1-3 17:39
4960
源代码如下:
// test_DecryptKey.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#pragma comment(lib,"1.lib")
#pragma comment(lib,"2.lib")


int DecryptKey(const unsigned char* pEncryptKey, int nEncryptKeyLen, unsigned char*& pKey, int& nLen);

unsigned char pEncryptKey [0x0040] =
{
	0xed, 0x6a, 0x7f, 0xb9, 0x7f, 0xf5, 0xf1, 0x40, 0x4d, 0x3c, 0xf6, 0xe2, 0xbf, 0x26, 0x62, 0x1b,
		0x95, 0xbe, 0x3a, 0x3a, 0xf0, 0x72, 0x69, 0xf9, 0xa9, 0x8d, 0xb8, 0x1f, 0xe7, 0xe9, 0x5c, 0x6f,
		0x99, 0xa6, 0xd8, 0x7c, 0x97, 0x12, 0xc2, 0xfd, 0x5b, 0x4a, 0xa2, 0xe0, 0x0a, 0x90, 0x1b, 0x85,
		0x7c, 0x09, 0x70, 0x14, 0x95, 0xf3, 0x9f, 0x0b, 0xc6, 0x00, 0x6c, 0x98, 0x38, 0xf0, 0x5d, 0xd8
};


int main(int argc, char* argv[])
{

	unsigned char *pDecryptKey = NULL;
	int nLen = 0;
	int nEncryptKeyLen = sizeof(pEncryptKey);
	int nRet = DecryptKey(pEncryptKey, nEncryptKeyLen, pDecryptKey, nLen);
	free(pDecryptKey);
	return 0;
}


编译后的文件和调试信息:

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 215
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
BOOL DecryptKey(const unsigned char* pIn, int nInLen, unsigned char*& pOut, int& nOutLen)
{
	unsigned char MyArray [0x0090] =
	{
		0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00,
		0x91, 0x43, 0x7c, 0xd8, 0x3d, 0x07, 0x22, 0xce, 0x41, 0x0b, 0xd9, 0x6c, 0xa8, 0x0c, 0xff, 0x34,
		0x89, 0x5a, 0x31, 0x5e, 0x25, 0x12, 0x8b, 0xc3, 0x25, 0x29, 0xd5, 0xf6, 0x14, 0xe4, 0x50, 0x97,
		0xe1, 0x2e, 0x45, 0x0c, 0x68, 0xda, 0xf1, 0xad, 0x8d, 0x8e, 0x74, 0x0a, 0xb7, 0x08, 0x56, 0x4f,
		0x4f, 0x31, 0x7b, 0x80, 0x12, 0xc4, 0x48, 0x56, 0xde, 0x56, 0x7d, 0x58, 0x52, 0x24, 0x97, 0xdb,
		0xf3, 0x84, 0xff, 0x17, 0xa8, 0x16, 0x5a, 0x0e, 0xce, 0xb0, 0xa5, 0x26, 0xf5, 0x44, 0x12, 0xa9,
		0x9a, 0x88, 0xec, 0x69, 0x68, 0xb5, 0xe1, 0x4f, 0xaf, 0x7a, 0x08, 0xbe, 0xe9, 0x2f, 0xfd, 0xe3,
		0x5b, 0x18, 0xc5, 0x46, 0x97, 0xd8, 0x6e, 0xcc, 0x63, 0x97, 0x00, 0xe6, 0x42, 0xbc, 0x91, 0x75,
		0x7e, 0x52, 0x2d, 0xc5, 0xef, 0x4c, 0x95, 0xcc, 0xd7, 0x46, 0xd2, 0xd2, 0x59, 0xdb, 0x00, 0xc5
	}; 
	return RSADecodeFunction(pIn, nInLen, MyArray, 0x90u, &pOut, (long*)&nOutLen) == 0;
}


ida中F5如下

signed int __stdcall RSADecodeFunction(const unsigned __int8 *a1, __int32 a2, const unsigned __int8 *a3, unsigned __int32 a4, unsigned __int8 **a5, __int32 *a6)
{
  signed int result; // eax@6
  int v7; // eax@7
  signed int v8; // edi@7
  void *v9; // eax@7
  unsigned __int8 *v10; // edx@7
  void *v11; // ebx@7
  __int32 v12; // esi@7
  __int32 v13; // esi@13
  unsigned __int8 *v14; // eax@15
  int v15; // [sp+0h] [bp-70h]@1
  bool v16[4]; // [sp+Ch] [bp-64h]@5
  char v17; // [sp+1Ah] [bp-56h]@6
  char v18; // [sp+27h] [bp-49h]@6
  char v19; // [sp+34h] [bp-3Ch]@6
  char v20; // [sp+41h] [bp-2Fh]@6
  char v21; // [sp+4Eh] [bp-22h]@6
  int *v22; // [sp+60h] [bp-10h]@1
  int v23; // [sp+6Ch] [bp-4h]@1
  unsigned __int8 *v24; // [sp+80h] [bp+10h]@7

  v22 = &v15;
  v23 = 0;
  if ( a1 && a3 && a5 && a6 )
  {
    RSAStruct::RSAStruct((int)v16);
    LOBYTE(v23) = 1;
    if ( RSAStruct::FromKeyBuffer((RSAStruct *)v16, a3, a4) )
    {
      v7 = RSAStruct::GetBytes((RSAStruct *)v16);
      v8 = v7;
      v9 = malloc((v7 - 1) * ((a2 - 1) / v7 + 1));
      v10 = 0;
      v11 = v9;
      v24 = 0;
      v12 = 0;
      while ( v12 < a2 )
      {
        if ( a2 - v12 < v8 )
          RSAStruct::Decode((RSAStruct *)v16, &a1[v12], a2 - v12, (unsigned __int8 *)v11 + v12 - (_DWORD)v10, v16[0]);
        else
          RSAStruct::Decode((RSAStruct *)v16, &a1[v12], v8, (unsigned __int8 *)v11 + v12 - (_DWORD)v10, v16[0]);
        v12 += v8;
        v10 = ++v24;
      }
      v13 = *(_DWORD *)v11;
      *a6 = *(_DWORD *)v11;
      if ( v13 < (v8 - 1) * (a2 / v8) - 2 * v8 || v13 > a2 )
      {
        free(v11);
        LOBYTE(v23) = 11;
        Integer::~Integer((Integer *)&v21);
        LOBYTE(v23) = 10;
        Integer::~Integer((Integer *)&v20);
        LOBYTE(v23) = 9;
        Integer::~Integer((Integer *)&v19);
        LOBYTE(v23) = 8;
        Integer::~Integer((Integer *)&v18);
        LOBYTE(v23) = 7;
        Integer::~Integer((Integer *)&v17);
        LOBYTE(v23) = 0;
        Integer::~Integer((Integer *)&v16[1]);
        result = 4;
      }
      else
      {
        v14 = (unsigned __int8 *)malloc(v13);
        *a5 = v14;
        qmemcpy(v14, (char *)v11 + 4, *a6);
        free(v11);
        LOBYTE(v23) = 16;
        Integer::~Integer((Integer *)&v21);
        LOBYTE(v23) = 15;
        Integer::~Integer((Integer *)&v20);
        LOBYTE(v23) = 14;
        Integer::~Integer((Integer *)&v19);
        LOBYTE(v23) = 13;
        Integer::~Integer((Integer *)&v18);
        LOBYTE(v23) = 12;
        Integer::~Integer((Integer *)&v17);
        LOBYTE(v23) = 0;
        Integer::~Integer((Integer *)&v16[1]);
        result = 0;
      }
    }
    else
    {
      LOBYTE(v23) = 6;
      Integer::~Integer((Integer *)&v21);
      LOBYTE(v23) = 5;
      Integer::~Integer((Integer *)&v20);
      LOBYTE(v23) = 4;
      Integer::~Integer((Integer *)&v19);
      LOBYTE(v23) = 3;
      Integer::~Integer((Integer *)&v18);
      LOBYTE(v23) = 2;
      Integer::~Integer((Integer *)&v17);
      LOBYTE(v23) = 0;
      Integer::~Integer((Integer *)&v16[1]);
      result = 3;
    }
  }
  else
  {
    result = 2;
  }
  return result;
}


char __thiscall RSAStruct::FromKeyBuffer(RSAStruct *this, const unsigned __int8 *a2, unsigned __int32 a3)
{
  int v3; // edx@2
  char result; // al@3

  if ( *(_DWORD *)a2 )
    goto LABEL_9;
  v3 = *((_DWORD *)a2 + 1);
  if ( v3 == 2 )
  {
    *(_BYTE *)this = 1;
    return RSAStruct::FromPriKeyBuffer(this, a2, a3);
  }
  if ( v3 != 1 )
  {
LABEL_9:
    result = 0;
  }
  else
  {
    *(_BYTE *)this = 0;
    result = RSAStruct::FromPubKeyBuffer(this, a2, a3);
  }
  return result;
}


char __thiscall RSAStruct::FromPubKeyBuffer(RSAStruct *this, const unsigned __int8 *a2, unsigned __int32 a3)
{
  RSAStruct *v3; // ebx@1
  int v4; // eax@1
  char result; // al@2

  v3 = this;
  v4 = *((_DWORD *)a2 + 2);
  if ( *((_DWORD *)a2 + 3) + v4 + 16 == a3 )
  {
    Integer::FromBuffer((RSAStruct *)((char *)this + 27), a2 + 16, v4);
    Integer::FromBuffer((RSAStruct *)((char *)v3 + 53), &a2[*((_DWORD *)a2 + 2) + 16], *((_DWORD *)a2 + 3));
    result = 1;
  }
  else
  {
    result = 0;
  }
  return result;
}


void __thiscall RSAStruct::Decode(RSAStruct *this, const unsigned __int8 *a2, unsigned __int32 a3, unsigned __int8 *a4, bool a5)
{
  RSAStruct *v5; // esi@1
  int v6; // eax@2
  Integer *v7; // ecx@2
  int v8; // eax@3
  char v9; // [sp+4h] [bp-3Ch]@1
  char v10; // [sp+14h] [bp-2Ch]@1
  char v11; // [sp+24h] [bp-1Ch]@2
  int v12; // [sp+3Ch] [bp-4h]@1

  v5 = this;
  Integer::Integer((Integer *)&v10);
  v12 = 0;
  Integer::FromBuffer((Integer *)&v10, a2, a3);
  Integer::Integer((Integer *)&v9);
  LOBYTE(v12) = 1;
  if ( a5 )
  {
    v6 = a_exp_b_mod_c(&v11, &v10, (char *)v5 + 66, (char *)v5 + 27);
    LOBYTE(v12) = 2;
    Integer::operator=((Integer *)&v9, v6);
    LOBYTE(v12) = 1;
    v7 = (Integer *)&v11;
  }
  else
  {
    v8 = a_exp_b_mod_c(&v11, &v10, (char *)v5 + 53, (char *)v5 + 27);
    LOBYTE(v12) = 3;
    Integer::operator=((Integer *)&v9, v8);
    LOBYTE(v12) = 1;
    v7 = (Integer *)&v11;
  }
  Integer::~Integer(v7);
  Integer::ToBuffer((Integer *)&v9, a4, 4 * *((_DWORD *)v5 + 8) - 1);
  LOBYTE(v12) = 0;
  Integer::~Integer((Integer *)&v9);
  v12 = -1;
  Integer::~Integer((Integer *)&v10);
}
2016-1-3 17:44
0
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
3
这是 CryptoPP lib 使用的 Integer class。
a_exp_b_mod_c 就是rsa的 幂模函数( powermod )。

这里的key是RSA-512 。 用hex表示为:
RSA_C =
D85DF038986C00C60B9FF3951470097C851B900AE0A24A5BFDC212977CD8A6996F5CE9E71FB88DA9F96972F03A3ABE951B6226BFE2F63C4D40F1F57FB97F6AED

RSA_D=
C500DB59D2D246D7CC954CEFC52D527E7591BC42E6009763CC6ED89746C5185BE3FD2FE9BE087AAF4FE1B56869EC889AA91244F526A5B0CE0E5A16A817FF84F3

RSA_N=
DB972452587D56DE5648C412807B314F4F5608B70A748E8DADF1DA680C452EE19750E414F6D52925C38B12255E315A8934FF0CA86CD90B41CE22073DD87C4391

msg = RSA_C ^ RSA_D mod RSA_N =
499D72B90299CAB0D0664044F2144FAD32AEDB1C0A890D1300000018

字节倒序为:
msg=
18000000130D890A1CDBAE32AD4F14F2444066D0B0CA9902B9729D49
2016-1-4 17:14
0
雪    币: 215
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
请问是如何解密的?
有对应的openssl或者Crypto代码吗?

多谢了!
2016-1-5 07:01
0
雪    币: 215
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
一下代码运行就出错,

#include<openssl/rsa.h>

unsigned char key1 [0x40] =
{
        0x91, 0x43, 0x7c, 0xd8, 0x3d, 0x07, 0x22, 0xce, 0x41, 0x0b, 0xd9, 0x6c, 0xa8, 0x0c, 0xff, 0x34,
        0x89, 0x5a, 0x31, 0x5e, 0x25, 0x12, 0x8b, 0xc3, 0x25, 0x29, 0xd5, 0xf6, 0x14, 0xe4, 0x50, 0x97,
        0xe1, 0x2e, 0x45, 0x0c, 0x68, 0xda, 0xf1, 0xad, 0x8d, 0x8e, 0x74, 0x0a, 0xb7, 0x08, 0x56, 0x4f,
        0x4f, 0x31, 0x7b, 0x80, 0x12, 0xc4, 0x48, 0x56, 0xde, 0x56, 0x7d, 0x58, 0x52, 0x24, 0x97, 0xdb
};
unsigned char key2 [0x40] =
{
        0xf3, 0x84, 0xff, 0x17, 0xa8, 0x16, 0x5a, 0x0e, 0xce, 0xb0, 0xa5, 0x26, 0xf5, 0x44, 0x12, 0xa9,
        0x9a, 0x88, 0xec, 0x69, 0x68, 0xb5, 0xe1, 0x4f, 0xaf, 0x7a, 0x08, 0xbe, 0xe9, 0x2f, 0xfd, 0xe3,
        0x5b, 0x18, 0xc5, 0x46, 0x97, 0xd8, 0x6e, 0xcc, 0x63, 0x97, 0x00, 0xe6, 0x42, 0xbc, 0x91, 0x75,
        0x7e, 0x52, 0x2d, 0xc5, 0xef, 0x4c, 0x95, 0xcc, 0xd7, 0x46, 0xd2, 0xd2, 0x59, 0xdb, 0x00, 0xc5
};

unsigned char MyArray [0x0040] =
{
        0xed, 0x6a, 0x7f, 0xb9, 0x7f, 0xf5, 0xf1, 0x40, 0x4d, 0x3c, 0xf6, 0xe2, 0xbf, 0x26, 0x62, 0x1b,
        0x95, 0xbe, 0x3a, 0x3a, 0xf0, 0x72, 0x69, 0xf9, 0xa9, 0x8d, 0xb8, 0x1f, 0xe7, 0xe9, 0x5c, 0x6f,
        0x99, 0xa6, 0xd8, 0x7c, 0x97, 0x12, 0xc2, 0xfd, 0x5b, 0x4a, 0xa2, 0xe0, 0x0a, 0x90, 0x1b, 0x85,
        0x7c, 0x09, 0x70, 0x14, 0x95, 0xf3, 0x9f, 0x0b, 0xc6, 0x00, 0x6c, 0x98, 0x38, 0xf0, 0x5d, 0xd8
};

        rsa = RSA_new();
        BIGNUM *ret, *a, *b, *c;
        BN_CTX *ctx = NULL;
        if ((ctx = BN_CTX_new()) == NULL)
                return NULL;
        BN_CTX_start(ctx);
        ret  = BN_CTX_get(ctx);
        a  = BN_CTX_get(ctx);
        b  = BN_CTX_get(ctx);
        c  = BN_CTX_get(ctx);
        a->dmax = 16;
        b->dmax = 16;
        c->dmax = 16;
        ret->dmax = 16;
        a->top = 16;
        b->top = 16;
        c->top = 16;
        ret->top = 16;

        memcpy_s(a->d, 64, MyArray, 64);
        memcpy_s(b->d, 64, key1, 64);
        memcpy_s(c->d, 64, key2, 64);
       
       
        int n = BN_num_bytes(a);
        if (!rsa->meth->bn_mod_exp(ret, a, b, c, ctx,
                rsa->_method_mod_n))
                return NULL;

======================
Windows 已在 openssl_rsa.exe 中触发一个断点。

其原因可能是堆被损坏,这说明 openssl_rsa.exe 中或它所加载的任何 DLL 中有 Bug。

原因也可能是用户在 openssl_rsa.exe 具有焦点时按下了 F12。

输出窗口可能提供了更多诊断信息。
2016-1-5 10:07
0
雪    币: 215
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
char* ReverseByPointer(char* original, int nLen)
{
        char* pText = original;
        char* pStart = pText;
        char* pEnd = pText + nLen - 1;
        for (int i = nLen / 2; i >= 0; i--)
        {
                char temp = *pStart;
                *pStart++ = *pEnd;
                *pEnd-- = temp;
        }

        return original;
}

int main(int argc, char *argv[])
{
        cBigInt m_1, m_2, m_3, Y;
        int r;
       
//        ReverseByPointer((char*)key1,64);
//        ReverseByPointer((char*)key2,64);
//        ReverseByPointer((char*)MyArray,64);

        r = m_1.ReadForm(key1, 64);
        r = m_2.ReadForm(key2, 64);
        r = m_3.ReadForm(MyArray, 64);

        Y = m_1.ModExp(m_2, m_3);
        Y = m_1.ModExp(m_3, m_2);
        Y = m_2.ModExp(m_1, m_3);
        Y = m_2.ModExp(m_3, m_1);
        Y = m_3.ModExp(m_2, m_1);
        Y = m_3.ModExp(m_1, m_2);
        r = Y.m_nLength;

===================
用了个大数运算库,结果不正确啊,请问如何解决?
还有解密后的数据为什么还是512位啊?
2016-1-5 11:09
0
雪    币: 215
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
rsa = RSA_new();
        BIGNUM *ret, *a, *b, *c;
        BN_CTX *ctx = NULL;
        if ((ctx = BN_CTX_new()) == NULL)
                return NULL;
        BN_CTX_start(ctx);
        ret  = BN_new();
        a  = BN_new();
        b  = BN_new();
        c  = BN_new();
        a->dmax = 16;
        b->dmax = 16;
        c->dmax = 16;
        a->top = 16;
        b->top = 16;
        c->top = 16;

        a->d =         (BN_ULONG*)key1;
        b->d =         (BN_ULONG*)key2;
        c->d =         (BN_ULONG*)MyArray;

       
        if (!rsa->meth->bn_mod_exp(ret, c, b, a, ctx,rsa->_method_mod_n))
        {
                ERR_load_crypto_strings();
                char errBuf[512];
                ERR_error_string_n(ERR_get_error(), errBuf, sizeof(errBuf));
                return NULL;
        }
        int n = BN_num_bytes(ret);

==========================
这个方式搞定.

不明白为什么用大数库都不成功?
2016-1-5 11:35
0
雪    币: 2735
活跃值: (2171)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
8
之前遇到过java rsa用c++实现,主要提出n和e
2016-1-5 12:42
0
雪    币: 11705
活跃值: (975)
能力值: ( LV12,RANK:779 )
在线值:
发帖
回帖
粉丝
9
http://tools.pediy.com/windows/cryptography.htm

BigIntCalc_v1.13         readyu         大整数计算器

用 大整数计算器 可以直接计算  x^y mod z。

2016-1-11 12:25
0
游客
登录 | 注册 方可回帖
返回
//