我正在尝试在crypto ++库中使用salsa20代码。 (THIS)在两个程序之间进行通信。
两个程序都使用相同的代码
std::string salsaDo(std::string key, std::string msg, byte iv[STREAM_IV_LENGTH]) {
//Set up byte arrays for proccess
byte *plaintextBytes = (byte *)msg.c_str();
byte *ciphertextBytes = new byte[msg.length()];
byte *reversetextBytes = new byte[msg.length()];
//Set up key array
byte* keyBytes = (byte *)key.substr(0, STREAM_KEY_LENGTH).c_str();
//Peform encryption method
Salsa20::Encryption salsa;
salsa.SetKeyWithIV(keyBytes, STREAM_KEY_LENGTH, iv);
salsa.ProcessData(ciphertextBytes, plaintextBytes, msg.length());
salsa.SetKeyWithIV(keyBytes, STREAM_KEY_LENGTH, iv);
salsa.ProcessData(reversetextBytes, ciphertextBytes, msg.length());
std::string ivStr((char*)iv, STREAM_IV_LENGTH);
std::cout << "____\nK:" << key.c_str();
std::cout << "\nI:" << ivStr.c_str();
std::cout << "\nM:" << msg.c_str();
std::cout << "\nE:" << std::string((const char *)ciphertextBytes, msg.length()).c_str();
std::cout << "\nR:" << std::string((const char *)reversetextBytes, msg.length()).c_str();
std::cout << "\n____\n";
//return msg;
//return string
return std::string((const char *)ciphertextBytes, msg.length());
}
程序中的图像位于http://www.cryptopp.com/
说明:
步骤1:加密纯文本(服务器-M到服务器-E)
步骤2:解密加密文本(Server-E到服务器-R,客户端-M到客户端-E。)这两个应该给出相同的结果,但不要
步骤3:再次运行client-E,检查它是否等于服务器发送的消息。
答案 0 :(得分:0)
此代码存在一些问题。
此行在技术上调用未定义的行为:
byte* keyBytes = (byte *)key.substr(0, STREAM_KEY_LENGTH).c_str();
在这种情况下,substr()
调用返回包含子字符串的临时std::string
对象。这个临时std::string
的生命周期延伸到整行的评估(完整表达式)。 std::string::c_str()
返回的C字符串的生存期与std::string
相同,但变异操作无效。因此,在这个完整的表达式中,keyBytes
一旦行执行就可能是无效指针。
您可以通过将key
覆盖到所需的子字符串来解决问题。在这种情况下,分配给key
可确保生命周期延长到使用位置:
key = key.substr(0, STREAM_KEY_LENGTH);
const byte* keyBytes = static_cast<const byte*>(key.c_str());
此salsaDo()
函数泄漏内存。由:
byte *ciphertextBytes = new byte[msg.length()];
byte *reversetextBytes = new byte[msg.length()];
..没有被释放。考虑使用std::unique_ptr<byte[]>
:
std::unique_ptr<byte[]> ciphertextBytes(new byte[msg.length()]);
std::unique_ptr<byte[]> reversetextBytes(new byte[msg.length()]);
C ++在技术上不支持将数组传递给函数。实际上,参数byte iv[STREAM_IV_LENGTH]
被视为您已经编写了byte* iv
。
您可以传递对数组的引用。另外,对于const-correctness,您应该标记初始化向量字节const
:
std::string salsaDo(std::string key, std::string msg, const byte (&iv)[STREAM_IV_LENGTH])
{
//...
}
std::string
来存储密钥,或者实际上是任何字节数组,例如返回的加密字节。考虑使用std::unique_ptr<byte[]>
或std::shared_ptr<byte[]>
,或者将引用传递给const数组,或传递指针和长度(例如const byte* key
和size_t keyLength
)。