我需要从标准输入读取密码,并且不想std::cin回显用户输入的字符...
如何禁用std :: cin的回声?
这是我目前使用的代码:
string passwd;
cout << "Enter the password: ";
getline( cin, passwd );
我正在寻找一种与操作系统无关的方法来做到这一点. 这里有一些方法可以在Windows和*nix中执行此操作.
我必须编写一个Windows服务,在某些时候处理机密数据(如PIN码,密码等).这些信息需要很短的时间:通常它们几乎立即被发送到智能卡读卡器.
让我们考虑这段代码:
{
  std::string password = getPassword(); // Get the password from the user
  writePasswordToSmartCard(password);
  // Okay, here we don't need password anymore.
  // We set it all to '\0' so it doesn't stay in memory.
  std::fill(password.begin(), password.end(), '\0');
}
现在我关心的是编译器优化.在这里,编译器可能会检测到密码即将被删除,并且此时更改其值是无用的,只需删除该调用即可.
我不希望我的编译器关心未来未引用的内存的价值.
我的担忧是否合法?我怎么能确定这样的代码不会被优化?
我正在做一些维护工作,遇到类似以下的事情:
std::string s;
s.resize( strLength );  
// strLength is a size_t with the length of a C string in it. 
memcpy( &s[0], str, strLength );
我知道使用&s [0]如果它是std :: vector会是安全的,但是这是std :: string的安全使用吗?
这是一个功能:
void foo() {
   string str = "StackOverflo";
   str.push_back('w');
}
当我们在函数内部声明字符串时,它是存储在堆栈还是堆中?为什么?
string foo() {
   string str = "StackOverflo";
   str.push_back('w');
   return str;
}
我们可以返回字符串引用并继续使用程序中的其他位置吗?
在这里讨论之后,如果你想要一个安全的类来存储内存中的敏感信息(例如密码),你必须:
所以这听起来不错,我创建了一个测试类来查看它是否有效.所以我做了一个简单的测试用例,我继续添加单词"LOL"和"WUT",然后在这个安全缓冲类中加上一个数字大约一千次,破坏该对象,然后再做一些导致核心转储的事情.
由于该类应该在破坏之前安全地清除内存,因此我不应该在coredump上找到"LOLWUT".但是,我设法找到它们,并想知道我的实现是否只是错误.但是,我尝试使用CryptoPP库的SecByteBlock做同样的事情:
#include <cryptopp/osrng.h>
#include <cryptopp/dh.h>
#include <cryptopp/sha.h>
#include <cryptopp/aes.h>
#include <cryptopp/modes.h>
#include <cryptopp/filters.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
using namespace std;
int main(){
   {
      CryptoPP::SecByteBlock moo;
      int i;
      for(i = 0; i < 234; i++){
         moo += (CryptoPP::SecByteBlock((byte*)"LOL", 3));
         moo += (CryptoPP::SecByteBlock((byte*)"WUT", 3));
         char buffer[33];
         sprintf(buffer, "%d", i);
         string thenumber (buffer);
         moo += (CryptoPP::SecByteBlock((byte*)thenumber.c_str(), thenumber.size()));
      }
      moo.CleanNew(0);
   }
   sleep(1);
   *((int*)NULL) = 1;
   return 0;
}
然后编译使用:
g++ clearer.cpp -lcryptopp …我正在玩内存动态分配,但我不明白.当用new语句分配一些内存时,我应该能够破坏指针指向使用的内存delete.
但是当我尝试时,这个delete命令似乎不起作用,因为指针指向的空间似乎没有被清空.
让我们以这个真正基本的代码为例:
#include <iostream>  
using namespace std;
int main()  
{  
    //I create a pointer-to-integer pTest, make it point to some new space,  
    // and fulfill this free space with a number;  
    int* pTest;  
    pTest = new int;  
    *(pTest) = 3;  
    cout << *(pTest) << endl; 
    // things are working well so far. Let's destroy this
    // dynamically allocated space!
    delete pTest;
    //OK, now I guess the data pTest pointed to has been destroyed …这个问题遵循@sharptooth在这个相关问题中提出的建议.
可以std::string调整,以便它变得密码安全吗?
如果没有,什么是写有密码处理类(因此类,它大关心它写入内存和破坏之前将其清除)的指导方针?
这是OpenSSL 1.0.1i中OPENSSL_cleanse的实现
unsigned char cleanse_ctr = 0;
void OPENSSL_cleanse(void *ptr, size_t len)
{
    unsigned char *p = ptr;
    size_t loop = len, ctr = cleanse_ctr;
    while(loop--)
    {
        *(p++) = (unsigned char)ctr;
        ctr += (17 + ((size_t)p & 0xF));
    }
    p=memchr(ptr, (unsigned char)ctr, len);
    if(p)
        ctr += (63 + (size_t)p);
    cleanse_ctr = (unsigned char)ctr;
}
它看起来很复杂且线程不安全(通过读写全局变量cleanse_ctr).有人可以解释一下这个实现吗?用户是否需要关注其中可能的数据竞争?
c++ ×7
memory ×4
security ×2
string ×2
c ×1
c++03 ×1
cryptography ×1
memcpy ×1
new-operator ×1
openssl ×1
optimization ×1
passwords ×1
stdstring ×1
stl ×1