带有加密的std :: string的sqlite查询(无法识别的令牌)

时间:2014-02-02 11:54:52

标签: c++ sqlite encryption encoding

我有一个使用AES128加密的C ++ std::string,并希望将其写入sqllite数据库。我已经知道,我必须使用''' "转义""个字符,但似乎还有其他问题。

它说:

unrecognized token: "'""\235\211g\264\376\247\3348( ]tu\202\346\360\226h\205D\322-\373\347y"

我的查询如下:

UPDATE tablename
SET column='""\235\211g\264\376\247\3348( ]tu\202\346\360\226h\205D\322-\373\347y\315\|`\3206\245\220j6
\215&\301ww/\222R\352]\253,\362&\233ï\2530\322搜\377\321!\334t\224\271ќVu\214Z\\256""\242O\254\241\254\365\360<P\364\356\370\225jnۢ\231\335($\243\377fH\225\215\224\223\254\316' 
WHERE index='1';

使用未加密字符串的相同查询有效。有什么想法吗?

1 个答案:

答案 0 :(得分:4)

你做错了。

您不应该永远,在查询中完整地写出参数;但您应该使用绑定参数Binding Values To Prepared Statements

主要优势?绑定参数不必转义,这完全可以防止SQL注入的任何风险,并且还大大简化了您的生活!

此外,准备好的陈述可以重复使用以提高效率,所以让我举一个完整的例子。

//
// WARNING: for concision purposes there is no error handling
//          and no attempt at making this code even remotely exception-safe.
//
// !!! DO NOT USE IN REAL LIFE !!!
//
void update(std::map<int, std::string> const& blobs) {
    // 1. Prepare statement
    sqlite3_stmt *stmt;

    sqlite3_prepare(db, 
                    "update tablename set column = ? where index = ?",
                    -1, // statement is a C-string
                    &stmt,
                    0  // Pointer to unused portion of stmt
    );

    // 2. Use statement as many times as necessary
    for (auto const& pair: blobs) {
        int const index = pair.first;
        std::string const& blob = pair.second;

        // 2.1 Bind 1st parameter
        sqlite3_bind_text(stmt,
                          1,  // 1-based index: 1st parameter
                          blob.data(),
                          blob.size(),
                          0   // no need for sqlite to free this argument
        );

        // 2.2 Bind 2nd parameter
        sqlite3_bind_int(stmt,
                         2, // 1-based index: 2nd parameter
                         index
        );

        // 2.3 Execute statement
        sqlite3_step(stmt);

        // 2.4 Reset bindings
        sqlite3_reset(stmt);
    }

    // 3. Free prepared query
    sqlite3_finalize(stmt);
} // update

注意:您当然可以将准备好的陈述保持更长时间。