此加密是否足够强大?

时间:2018-03-28 02:45:35

标签: c++ encryption cryptography password-protection password-encryption

前段时间我发布了这个,有人在几个小时内破解了它,我做了一些修改,想知道这是否足够强大。 我不是怪物,所以我会告诉你背后的代码:

int StrToNum(string text){
    int result;
    stringstream convert(text);
    if (!(convert >> result))result = 0;
    return result;
}

static const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";


static inline bool is_base64(unsigned char c) {
    return (isalnum(c) || (c == '+') || (c == '/'));
}

string B64E(unsigned char const* bytes_to_encode, unsigned int in_len) {
    std::string ret;
    int i = 0;
    int j = 0;
    unsigned char char_array_3[3];
    unsigned char char_array_4[4];

    while (in_len--) {
        char_array_3[i++] = *(bytes_to_encode++);
        if (i == 3) {
            char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
            char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
            char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
            char_array_4[3] = char_array_3[2] & 0x3f;

            for (i = 0; (i <4); i++)
                ret += base64_chars[char_array_4[i]];
            i = 0;
        }
    }

    if (i)
    {
        for (j = i; j < 3; j++)
            char_array_3[j] = '\0';

        char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
        char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
        char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
        char_array_4[3] = char_array_3[2] & 0x3f;

        for (j = 0; (j < i + 1); j++)
            ret += base64_chars[char_array_4[j]];

        while ((i++ < 3))
            ret += '=';

    }

    return ret;

}

string B64D(std::string const& encoded_string) {
    int in_len = encoded_string.size();
    int i = 0;
    int j = 0;
    int in_ = 0;
    unsigned char char_array_4[4], char_array_3[3];
    std::string ret;

    while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
        char_array_4[i++] = encoded_string[in_]; in_++;
        if (i == 4) {
            for (i = 0; i <4; i++)
                char_array_4[i] = base64_chars.find(char_array_4[i]);

            char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
            char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
            char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

            for (i = 0; (i < 3); i++)
                ret += char_array_3[i];
            i = 0;
        }
    }

    if (i) {
        for (j = i; j <4; j++)
            char_array_4[j] = 0;

        for (j = 0; j <4; j++)
            char_array_4[j] = base64_chars.find(char_array_4[j]);

        char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
        char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
        char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

        for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
    }

    return ret;
}

string Encrypt(string text, string key){
    string enc = "";
    //B64E encodes to base64
    text = B64E(reinterpret_cast<const unsigned char *>(text.c_str()), text.length());
    for(int i = 0; i < text.length(); ++i){
        char ascii = text[i];
        stringstream ss;
        ss << int(ascii);
        string code = ss.str();
        if(code.length() < 3) code = "0" + code;
        for(int j = 0; j < 3; j ++){
            string letter = code.substr(j, +1);
            enc += key[StrToNum(letter)];
        }
    }
    return enc;
}

string Decrypt(string text, string key){
    string dec = "";
    for(int i = 0; i < text.length(); i += 3){
        string group = text.substr(i, +3);
        stringstream ss;
        for(int j = 0; j < 3; ++j){
            string letter = group.substr(j, +1);
            int pos = key.find(letter);
            ss << pos;
        }
        int num = StrToNum(ss.str());
        char c = num;
        dec += c;
    }
    return B64D(dec);
}

如果您对此感到满意,请输入以下信息:

ZS%ZSSZSQ%MM%ZZZ&安培; MZ&安培; R%ZRZ = SZ&安培; %% ZS%ZRZ&安培;·Z&安培; ZZ&安培; RZR = Z = SZ&安培;%ZSQ%MM

2 个答案:

答案 0 :(得分:3)

你的代码遇到很多问题。

1-在开始时,您添加了一个不执行安全加密的base64编码器。它没有增加额外的安全性,因为它很容易逆转。因此,这是一个微不足道的步骤,它模糊但没有加密。

2-这一行

if(code.length() < 3) code = "0" + code;

不保证code的长度必须3。你需要一个while循环。

3-您使用索引键。那太糟了!无法保证索引不在密钥范围之外。使用短键时很容易崩溃。

4-我打赌你不能通过这个当前的设计解密。它看起来像哈希而不是加密。想象一下,钥匙中的两个字母是相似的。加密变得不可逆转。你能提供解密功能吗?

我们试一试:

string message="ICAgICAgICAg";
string key="arash";
string encrypted=Encrypt(message,key);
string decrypted=Decrypt(encrypted,key);
cout<<"-------------------------"<<endl;
cout<<"message: "<<message<<endl;
cout<<"key: "<<key<<endl;
cout<<"encrypted: "<<encrypted<<endl;
cout<<"decrypted: "<<decrypted<<endl;

结果:

-------------------------
message: ICAgICAgICAg
key: arash
encrypted: asaaaaaahraaararaaaharahaarra
decrypted: 

我在加密消息中看到密钥的字符。那太糟糕了。

您的代码也因非法的超出内存访问而具有未定义的行为:

之前:

  enc += key[StrToNum(letter)];

请为内存检查添加以下行:

if(StrToNum(letter)>=key.length())
{
    stringstream sse;
    sse<<"index["<<StrToNum(letter)<<"]: ";
    sse<<" length: "<<key.length();
    throw runtime_error(sse.str());
}

我看到以下异常:

terminate called after throwing an instance of 'std::runtime_error'
  what():  index[8]:  length: 5
Aborted (core dumped)

答案 1 :(得分:3)

在您的算法下,并在相同的密钥下,请参阅以下结果:

  • “你好”:Z =&amp; Z&amp;%ZSQ %% $ Z = SZ&amp;%Z $ QZQ%
  • “Helln”:ZS#Z&amp;%ZSQ %% $ Z = SZ&amp;%Z $ MZQ%

现在,请参阅下面的AES结果:

  • “你好”:TUkvMW2Z6zVVPS4BXKIIRA ==
  • “Helln”:k9EAZxqlUT9ItvLnk51UfA ==

请注意,在您的算法中,密文的变化与明文的变化成比例。这不是AES的问题。你的算法的这个属性使得除了作为游戏,铅笔拼图等玩具密码之外的其他任何东西都毫无用处。

我还建议您使用密钥AAAAAAAAAAAAAAAA加密字符串BBBBBBBBBBBBBBBB并观察输出。这对您来说是否也是一个问题?

总之,您的算法没用。设计安全,强大,有用的加密算法需要多年的经验和理解,大多数人,包括你自己,都没有。