I just finished implementing a secure chat feature in NinjaChat. If you can tell me what ninja9578s^slave and I said to each other and how you cracked it, you win a $500 prize.
Session negotiation
Code:
PRIVMSG ninja9578s^slave : ENCRYPT INVITE pHV9sLOusoamj5eQeXKU1tXq0YJxsLlxd4x7moF9e4WtrMW6nHp7dU2Rr7jmw3mPuZ6mh56aeaq8kW1efb2vww==
PRIVMSG ninja9578 :ENCRYPT ACK oI2Osa6/jrzSn8iWulfXtdbRo3943aiSho+PzZ+dltO2juOGupyUYIufm+jknn+dwJTKZNV+gqzUZqiN1JO8xKWfbuWjqHWoxJHYYbt5o8nX24qgvuCNXg==
PRIVMSG ninja9578s^slave :ENCRYPT ACKACK pHV9sLOusoamj5eQeXKU1tXq0YJxsLlxd4x7moF9e4WtrMW6nHp7dU2Rr7jmw3m{0}{0}n{0}5x{0}{16}ea<y{0}9${0}{0}{0}{0}{0}{0}^
PRIVMSG ninja9578 :ENCRYPT CONNECTED
(Any number in braces is an invisible value. ie {0} is character 0, {16} is character 16 on the ascii table)
Conversation you need to decode
Code:
PRIVMSG ninja9578s^slave :ENCRYPT M3Vreq7foL3EXIeMsZCS3eDueJKsysJBw5uE
PRIVMSG ninja9578 :ENCRYPT M3VrerTYsnN/k8iXcJvh2ZHhvYu5ib2GlQ==
PRIVMSG ninja9578s^slave :ENCRYPT M3VreoSToqjNXIeStkLT0uroxo9nzryUu1auyEzDj7y2w9m2baG2kJmXZOjXvZSHv7F6jt+NcNPRpF6Xxs5v1VBpbahrk6+5yKrM
It shouldn't be crackable even if you know how it works, so here is how it works:
This is the encryption and decryption code:
Code:
QString tab_chat::encrypt(QString _str, const string & key){
string str = _str.toStdString();
string::iterator i = str.begin();
string::iterator end = str.end();
string::const_iterator keyi = key.begin();
string::const_iterator keyend = key.end();
string result;
for(;i != end; ++i){
++keyi;
if (keyi == keyend){
keyi = key.begin();
keyend = key.end();
}
unsigned char strc = (unsigned char)*i;
unsigned char keyc = (unsigned char)*keyi;
short resc = (short)strc + (short)keyc;
if (resc > 255) resc -= 255;
result += (char)resc;
}
QByteArray tmp = QByteArray(result.c_str()).toBase64();
return QString(tmp);
}
QString tab_chat::decrypt(QString _str, const string & key){
string str = QString(QByteArray::fromBase64(_str.toAscii())).toStdString();
string::iterator i = str.begin();
string::iterator end = str.end();
string::const_iterator keyi = key.begin();
string::const_iterator keyend = key.end();
string result;
for(;i != end; ++i){
++keyi;
if (keyi == keyend){
keyi = key.begin();
keyend = key.end();
}
unsigned char strc = (unsigned char)*i;
unsigned char keyc = (unsigned char)*keyi;
short resc = (short)strc - (short)keyc;
if (resc < 1) resc += 255;
result += (char)resc;
}
return result.c_str();
}
Here is the algorithm
ninja creates a random 768 bit public key
ninja creates a random 768 bit private key
ninja sends the slave the public key encrypted in ninja's private key (INVITE)
slave creates a random 768 bit private key
slave sends ninja what was just sent to it, encrypted in slave's private key (ACK)
ninja decrypts what was just sent to it with ninja's private key (ACKACK)
slave decrypts what was just sent to it with slave's private key
slave now has public key
slave sends CONNECTED
ninja and slave now talk to each other by encrypting data with the public key
Have fun. If you need clarification of how any parts of this work, let me know.
Bookmarks