前段时间我发布了这个,有人在几个小时内破解了它,我做了一些修改,想知道这是否足够强大。 我不是怪物,所以我会告诉你背后的代码:
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
答案 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)
在您的算法下,并在相同的密钥下,请参阅以下结果:
现在,请参阅下面的AES结果:
请注意,在您的算法中,密文的变化与明文的变化成比例。这不是AES的问题。你的算法的这个属性使得除了作为游戏,铅笔拼图等玩具密码之外的其他任何东西都毫无用处。
我还建议您使用密钥AAAAAAAAAAAAAAAA
加密字符串BBBBBBBBBBBBBBBB
并观察输出。这对您来说是否也是一个问题?
总之,您的算法没用。设计安全,强大,有用的加密算法需要多年的经验和理解,大多数人,包括你自己,都没有。