【问题标题】:Openssl base64 decoded string does not always decryptOpenssl base64解码字符串并不总是解密
【发布时间】:2012-06-02 05:01:12
【问题描述】:

我正在尝试使用 RSA_public_encrypt() 使用公钥加密一些纯文本,然后将这些数据发送到远程服务器进行验证。我相信我的加密/解密工作正常,因为 RSA_public_encrypt 的输出可以传递给 RSA_private_decrypt 并且它可以工作。我现在遇到的问题是我需要对数据进行 base64 编码以便通过 HTTP 发送它。

作为测试(在将其发送到服务器之前),我将 RSA_public_encrypt() 的输出编码为 base64,然后对其进行解码并将其传递回 RSA_private_decrypt()。这似乎在某些时候有效,但失败并出现如下错误:

error:0407A079:rsa routines:RSA_padding_check_PKCS1_OAEP:oaep decoding error

当我使用 memcmp 将原始数据(pre-base64)与我的 base64 解码函数的输出进行比较时,尽管内容看起来匹配,但我收到 -1(在 Visual Studio 中,通过将内存内容查看为十六进制) .我还使用各种在线工具检查了 base64 编码版本,它们似乎可以解码为预期值。

我已经仔细检查了 base64/unbase64 函数的输入/输出是否为空终止,这似乎没什么区别。

这几天我一直在纠结这个问题,但我相信这一定是 base64 编码/解码过程的问题,因为当不涉及这个问题时,一切正常。如果有人对如何发生这种情况有任何建议,将不胜感激。

Openssl 版本: 1.0.1c

平台: Windows/MSVC

Base64 代码:

char *base64(const unsigned char *input, int length)
{
  BIO *bmem, *b64;
  BUF_MEM *bptr;
  char *buff = NULL;

  b64 = BIO_new(BIO_f_base64());
  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
  bmem = BIO_new(BIO_s_mem());
  b64 = BIO_push(b64, bmem);
  BIO_write(b64, input, length);
  BIO_flush(b64);
  BIO_get_mem_ptr(b64, &bptr);

  buff = (char *)malloc(bptr->length+1);
  memcpy(buff, bptr->data, bptr->length);
  buff[bptr->length] = '\0';

  BIO_free_all(b64);

  return buff;
}

Unbase64 代码:

char *unbase64(unsigned char *input, int length)
{
  BIO *b64, *bmem;

  char *buffer = (char *)malloc(length+1);
  memset(buffer, 0, length+1);

  b64 = BIO_new(BIO_f_base64());
  BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
  bmem = BIO_new_mem_buf(input, length);
  bmem = BIO_push(b64, bmem);

  BIO_read(bmem, buffer, length);
  buffer[length] = '\0';

  BIO_free_all(bmem);

  return buffer;
}

加密的“hello world”示例:

š:Œ¼JŒ"ÌïëŸÔè#¢Oo‚À–    œê\çrú¿±a/8ƒòÌ¢Q\T¹]nío

Base64 版本(使用上述代码):

G5qdOgWMvEqMIswZ7+uf1OgPI6JPb4LAlgmc6lzncvq/sWEvOIPyzByiUVwMjYFUuV0Vbu1v

感谢您的帮助!

【问题讨论】:

    标签: c windows openssl


    【解决方案1】:

    您在unbase64 函数中传递了正确的大小?它应该是返回的 base64 缓冲区的大小,而不是目标缓冲区的大小,即使用示例 main 函数:

    int main(void)
    {
      unsigned char bufron[2000];
      int i;
      char *chab;
      unsigned char *chac;
    
      for (i = 0; i < 2000; i++) {
          bufron[i] = i % 255;
      }
    
      chab = base64(bufron, 2000);
      printf("%s\n", chab);
    
      chac = unbase64(chab, strlen(chab));
    
      for (i = 0; i < 2000; i++) {
          if (bufron[i] != chac[i]) {
              printf("Failed at %d\n", i);
              return (1);
          }
      }
    }
    

    【讨论】:

    • 传递给unbase64 的尺寸是正确的,但是您的回答让我检查了所有尺寸。原来我在调用base64() 时没有使用正确的长度。我使用的是base64(str, strlen(str)),但二进制字符串必须包含 NULL。将其更改为 base64(str, 256) 解决了问题。 (其中 256 是 openssl 报告的字符串大小)。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-11
    相关资源
    最近更新 更多