首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OpenSSL和JSON文件加密和解密

OpenSSL和JSON文件加密和解密
EN

Stack Overflow用户
提问于 2017-02-15 21:11:50
回答 1查看 2.5K关注 0票数 1

我已经成功地使用openssl库加密了一个文件(jsonOut.crypto)。但是,我无法成功地将该加密文件读入char数组并使用下面的c++代码进行解密。

我将文件内容读入字符串(char数组),迭代该数组,同时解密16字节的缓冲区,将这16位插入数组中,并将该数组插入文件对象中。

然而,解密的文件看起来像胡言乱语。它与加密文件不同,但看起来仍然是加密的。有人能看看我的代码中是否有明显的错误吗?

请不要推荐其他图书馆。这不是为了获得尽可能高级别的密码而产生的代码--它只是快速地将一些东西组合在一起。

谢谢!

代码语言:javascript
复制
int main()
{
    // read json file into memory
    ifstream inFile;
    inFile.open("file.json");

    stringstream strStream;
    strStream << inFile.rdbuf();
    string str = strStream.str();

    // create buffer and buffer input/output
    int len = strlen(str.c_str());
    unsigned char encryptedbuffer[128];

    // CODE FOR ENCRYPTION
    unsigned char oneKey[] = "abcdefghijklmnop";
    AES_KEY key;

    // encryption - could make into function?
    AES_set_encrypt_key(oneKey,128,&key);

    ofstream outFile;
    outFile.open("jsonOut.crypto");

    for(int i = 0; i <= len; i += 16) {
        AES_encrypt((const unsigned char *) str.c_str() + i,encryptedbuffer,&key);
        for (int k = 0; k <= 16; k++) {
            outFile << encryptedbuffer[k];
        }
    }

    outFile.close();
    inFile.close();

    // read encrypted file into memory
    ifstream inEncryptedFile;
    inEncryptedFile.open("jsonOut.crypto");

    stringstream encryptedStreamStr;
    encryptedStreamStr << inEncryptedFile.rdbuf();
    string encryptedStr = encryptedStreamStr.str();

    // create buffer and buffer input/output
    int lenDecrypt = strlen(encryptedStr.c_str());
    unsigned char outbufferDecrypt[lenDecrypt];

    AES_set_decrypt_key(oneKey,128,&key);

    ofstream outFileDecrypt;
    outFileDecrypt.open("jsonOut.decrypt");

    for(int j = 0; j <= lenDecrypt; j += 16){
        AES_decrypt((const unsigned char *) encryptedStr.c_str() + j,outbufferDecrypt,&key);
        for (int k = 0; k <= 16; k++) {
            outFileDecrypt << outbufferDecrypt[k];
        }
    }

    outFileDecrypt.close();
    inEncryptedFile.close();

    return 0;
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-15 21:27:23

这里有一个明显的错误:

代码语言:javascript
复制
stringstream encryptedStreamStr;
encryptedStreamStr << inEncryptedFile.rdbuf();

这是你的加密文件。这是二进制数据。

代码语言:javascript
复制
string encryptedStr = encryptedStreamStr.str();

std::string用于文本字符串。不是二进制数据。尽管std::string不应该对以上述方式读取的二进制数据产生问题,但以下将是一个问题:

代码语言:javascript
复制
int lenDecrypt = strlen(encryptedStr.c_str());

strlen()是一个C库函数,它对C++字符串一无所知。它通过查找第一个'\0‘字节来确定字符串的长度。这不太可能给出加密二进制blob的真正大小,如果二进制blob一定有\0字节的话。所以,至少,加密文件的计算大小在这里是错误的。

在读取原始文件以加密时,所示代码也使用strlen。不清楚原始文件是纯文本还是二进制文件。如果被加密的文件是二进制文件,则在读取原始文件时也会发生相同的错误。

下一个问题:

代码语言:javascript
复制
for (int k = 0; k <= 16; k++) {
    outFile << encryptedbuffer[k];
}

这将向输出文件写入17个字节,而不是16字节,因为您的目的很明显。

在加密文件时也会发生同样的错误。被加密的原始文件马上就被破坏了。游戏结束。

总之:std::string指的是与文本字符串一起使用。虽然使用二进制数据可以正确、安全地使用std::string,但这往往会导致混淆。

std::vector<char>与二进制数据(而不是std::string )一起使用将不会让人感到困惑,从而使它明白这不是一个文本字符串。是二进制数据。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42260141

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档