c_str() 正在终止我的加密消息,有没有办法绕过这个?

c_str() is terminating my encrypted message is there a way to bypass this?

我正在使用 RSA 加密邮件。

如果我尝试在本地 encrypt/decrypt 消息,一切正常,但是,当将字符串转换为 void constant* 以便像这样使用 socket::send 方法时,

int sendRes = send(socket, tempMessage.c_str(), tempMessage.size() + 1, 0);

发生以下情况,

我原来的字符串,tempMessage

"_��JE�-��6����Pr��[͉dZ%�"

当使用 tempMessage.c_str()

时,

被截断为这个

"_��JE

我知道这个是因为,在加密过程中,有一个[=16=]符号被附加在一次或几次之间,因此在使用时终止那里的一切c_str().

我也知道它发生在使用 send() 之前,我把它放在这里是为了让你首先知道我为什么要使用 c_str()。

有办法绕过这个吗?或解决方法?

我看过 this 之前的回答,但对我的情况没有帮助,也找不到任何其他解决方案。

在此先感谢您的帮助!

这是一个简单的例子

  • 在包含空字符的字符串上显示 c_str() 的问题。
  • sending/receiving 个字符串的两个原语。

想法是 send/receive 字符串的长度在实际字符之前的固定字节数上。

/**
  g++ -std=c++17 -o prog_cpp prog_cpp.cpp \
      -pedantic -Wall -Wextra -Wconversion -Wno-sign-conversion \
      -g -O0 -UNDEBUG -fsanitize=address,undefined
**/

#include <iostream>
#include <string>
#include <stdexcept>

#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <unistd.h>

ssize_t
send_all(int sockfd,
         const void *buf,
         size_t len,
         int flags)
{
  const auto *p=static_cast<const char *>(buf);
  auto remaining=len;
  while(remaining)
  {
    const auto r=send(sockfd, p, remaining, flags);
    if(r<0)
    {
      return r;
    }
    remaining-=r;
    p+=r;
  }
  return len-remaining;
}

ssize_t
recv_all(int sockfd,
         void *buf,
         size_t len,
         int flags)
{
  char *p=static_cast<char *>(buf);
  auto remaining=len;
  while(remaining)
  {
    const auto r=recv(sockfd, p, remaining, flags);
    if(r<0)
    {
      return r;
    }
    if(r==0) // EOF
    {
      break;
    }
    remaining-=r;
    p+=r;
  }
  return len-remaining;
}

void
send_string(int sockfd,
            const std::string &str,
            int flags)
{
  const auto length=htonl(std::int32_t(size(str)));
  if(send_all(sockfd, &length, sizeof(length), flags)!=sizeof(length))
  {
    throw std::runtime_error{"cannot send length"};
  }
  if(send_all(sockfd, data(str), size(str), flags)!=
     static_cast<ssize_t>(size(str)))
  {
    throw std::runtime_error{"cannot send string"};
  }
}

std::string
recv_string(int sockfd,
            int flags)
{
  auto str=std::string{};
  auto length=std::int32_t{};
  const auto r=recv_all(sockfd, &length, sizeof(length), flags);
  if(r==0) // EOF
  {
    return str;
  }
  if(r!=sizeof(length))
  {
    throw std::runtime_error{"cannot receive length"};
  }
  str.resize(ntohl(length));
  if(recv_all(sockfd, data(str), size(str), flags)!=
     static_cast<ssize_t>(size(str)))
  {
    throw std::runtime_error{"cannot receive string"};
  }
  return str;
}

int
main()
{
  auto msg=std::string{};
  msg+="there is a nul-char...";
  msg+='[=10=]';
  msg+="in the middle!";
  std::cout << "as a string <" << msg << ">\n";
  std::cout << "as a const char * <" << msg.c_str() << ">\n";
  std::cout << "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n";
  int fd[2];
  if(socketpair(PF_LOCAL, SOCK_STREAM, 0, fd)<0)
  {
    throw std::runtime_error{"socketpair() failure"};
  }
  for(auto i=0; i<5; ++i) // very few to fit in internal buffer
  {
    send_string(fd[1], "message number "+std::to_string(i+1), 0);
  }
  close(fd[1]);
  for(;;)
  {
    const auto s=recv_string(fd[0], 0);
    if(empty(s))
    {
      break;
    }
    std::cout << '[' << s << "]\n";
  }
  close(fd[0]);
  return 0;
}
/**
as a string <there is a nul-char...in the middle!>
as a const char * <there is a nul-char...>
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[message number 1]
[message number 2]
[message number 3]
[message number 4]
[message number 5]
**/

最终,这是一个更容易解决的问题。

由于所有消息都按照相同的类型进行加密,因此加密部分的位长度将始终相同。

在我的例子中,这是 256,这意味着我现在可以毫无问题地发送-接收,因为我现在知道了真正的字符串长度。

如果不是这种情况,我会选择@prog-fh answer