代码之家  ›  专栏  ›  技术社区  ›  James Combs

通过套接字验证消息RSA签名方案时出现问题

  •  0
  • James Combs  · 技术社区  · 9 年前

    我试图通过套接字将签名消息从服务器发送到客户端。我无法验证消息。我尝试了基于维基上提供的代码示例的过滤和非过滤方法。我已经尝试了几乎所有我能在谷歌上找到的东西,但我被卡住了。

       SERVER:
    
       try
       {
          AutoSeededRandomPool rng;
          stringstream ss;
          string signature;
    
    //      byte* signature = new byte[tdata->signer.MaxSignatureLength()];
    //      if( NULL == signature )
    //      {
    //         throw Exception(Exception::OTHER_ERROR, "Invalid Signature");
    //      }
    //
    //      size_t length = tdata->signer.SignMessage( rng, (const byte*) sendBuf.c_str(),
    //          sendBuf.length(), signature );
          //string signature;
    //    byte* message = (byte*) sendBuf.c_str();
    //    SecByteBlock signature(tdata->signer.MaxSignatureLength(sendBuf.size()));
    //
    //    size_t signatureLen = tdata->signer.SignMessageWithRecovery(rng, message,
    //             sendBuf.size(), NULL, 0, signature);
    //
    //    cout << "Signature Length: " << signatureLen << endl;
    //    ss << signatureLen;
    //    string len = ss.str();
    //    string send;
    //    send = (char*)signature.data();
    //    send += " " + len;
          StringSource(sendBuf, true,
                   new SignerFilter(rng, tdata->signer, new StringSink(signature),
                            true // putMessage
                            )// SignerFilter
                            );// StringSource
    
    //    cout << "Signature: " << std::hex << signature << endl;
    //    // Encode the message as an Integer
    //    m = Integer((const byte *) sendBuf.c_str(), sendBuf.size());
    //
    //    //Encrypt
    //    c = tdata->privateKey.CalculateInverse(rng, m);
    //
    //    //Turn the encrypted value into a string
    //    ss << c;
    //    sendBuf = ss.str();
    //    ss.str("");
    //    ss.clear();
    //    cout << "Cipher Sent: " << sendBuf << endl;
    
          tdata->sockSource.Send((byte*)signature.c_str(), sizeof(signature));
    

       CLIENT:
    
       string signature, recovered;
       stringstream ss("");
       AutoSeededRandomPool rng;
       byte byteBuf[ 1000 ];
    
       try
       {
          // Retrieve message from socket
          cout << "Waiting for reply from server..." << endl;
          sockServer.Receive(byteBuf, sizeof(byteBuf));
    
          ss << byteBuf;
          string signature = ss.str();
          ss.str("");
          ss.clear();
    
    //    byte sig[2048];
    //    bool result = verifier.VerifyMessage( (const byte*)message.c_str(),
    //        message.length(), sig, 2048 );
    //
    //    if( true == result )
    //    {
    //        cout << "Message Verified" << endl;
    //    }
    //    else
    //    {
    //        cout << "Message Verification Failed" << endl;
    //    }
    //    cout << endl << std::hex << "Cipher Received: " << byteBuf << endl;
    //
    //    SecByteBlock recovered(
    //             verifier.MaxRecoverableLengthFromSignatureLength(length));
    //
    //    DecodingResult result = verifier.RecoverMessage(recovered, NULL, 0,
    //             byteBuf, length);
    //
    //    if ( !result.isValidCoding )
    //    {
    //       throw Exception(Exception::OTHER_ERROR, "Invalid Signature");
    //    }
    //
    //    ////////////////////////////////////////////////
    //    // Use recovered message
    //    size_t recoveredLen = result.messageLength;
    //
    //    assert(
    //             0
    //                      == memcmp(byteBuf, (const byte* )recovered,
    //                               std::min(sizeof(byteBuf), recoveredLen)));
    
    //     Convert message to a string
    //    StringSource ss1(byteBuf, sizeof(byteBuf), true,
    //             new StringSink(temp));
    //
    //    ss << byteBuf;
    //    signature = ss.str();
    //    ss.str("");
    //    ss.clear();
    //
    //    cout << "Signature received: " << std::hex << signature << endl;
    //
          StringSource(signature, true,
                   new SignatureVerificationFilter(verifier,
                            new StringSink(recovered),
                            SignatureVerificationFilter::THROW_EXCEPTION
                                     | SignatureVerificationFilter::PUT_MESSAGE) // SignatureVerificationFilter
                                     );// StringSource
    
          cout << "Verified signature on message" << endl;
          return recovered;
    //    return recovered;
    
    //    //Convert the string to an Integer so we can calculate the inverse
    //    c = Integer(recBuf.c_str());
    //    r = serverKey.ApplyFunction(c);
    //    cout << "r: " << r << endl;
    //
    //    // Recover the original message
    //    size_t req = r.MinEncodedSize();
    //    recovered.resize(req);
    //    r.Encode((byte *) recovered.data(), recovered.size());
    //    cout << "Recovered: " << recovered << endl;
    
       }
       catch ( Exception& e )
       {
          cerr << "caught Exception..." << endl;
          cerr << e.what() << endl;
          sockServer.ShutDown(SHUT_RDWR);
          return "";
       }
    
    1 回复  |  直到 9 年前
        1
  •  1
  •   Sam Varshavchik    9 年前
    string signature;
    
    // ...
    
    tdata->sockSource.Send((byte*)signature.c_str(), sizeof(signature));
    

    A. std::string 是一个相对较小的类。我的 std::字符串 s是32字节长。所以,我的 sizeof(signature) 是32。

    你的 sizeof(签名) sizeof 是编译时间常数。它将是32,或16,或任何其他值,不管字符串是否包含几个字节,或几兆字节。

    你应该做的是使用 signature.size() 以确定要写入的字节数。

    此外,还不清楚您使用的是什么套接字API库,但对于大多数API,您不能保证成功发送请求的字节数。发送给定字节数的请求通常会返回写入的字节数,可能更少,在这种情况下,您需要重试。从套接字读取数据也是如此。你必须事先知道你希望接收多少字节,如果你读的字节更少,你就必须继续读。

    很可能您必须检查来自的返回值 Send() 和 Receive() ,并采取适当的行动。

    推荐文章