Hah. I tried absolutely everything. Almost every 64-bit block cipher imaginable, almost all modes, tons of phrases in all thinkable capitalizations as both IV and password. I even tried stream ciphers. In my latest attempt I added many hash functions in case the password is hashed.
Either there’s still a password to be found or it’s simply not a modern cipher.
But since you are on linux, I assume you are familiar with gcc (I’m a win guy, but this should work anywhere).
Here’s the source code of my program (you need Crypto++), it should be way faster than scripts:
[code]#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef unsigned char byte;
typedef unsigned int uint;
byte const Code[] {
0xB3, 0x2B, 0x00, 0x3A, 0x35, 0xBA, 0xDD, 0x66, 0x57, 0x7C, 0x24, 0xC1, 0x4F, 0xC9, 0x19, 0x06,
0x43, 0x46, 0xD1, 0x31, 0xA7, 0xC5, 0x4B, 0xB8, 0x2F, 0xFE, 0x03, 0xE0, 0x22, 0x61, 0x57, 0x77,
0x24, 0x79, 0x23, 0xDC, 0x21, 0xF6, 0x2C, 0xD4, 0x18, 0x2E, 0x91, 0xC3, 0xB2, 0x67, 0xB5, 0x45,
0xAB, 0xCA, 0xED, 0xAF, 0x02, 0x61, 0x51, 0x0D, 0x4E, 0xEA, 0x1E, 0x87, 0xCD, 0x33, 0xC7, 0xC7,
0x71, 0x31, 0x30, 0x9C, 0xC4, 0x28, 0x0E, 0xB4, 0x24, 0x3D, 0x11, 0x54, 0xF0, 0x44, 0xF9, 0xCF,
0x62, 0x96, 0xD9, 0xBF, 0xF7, 0x39, 0x7E, 0x43, 0x90, 0x98, 0x7F, 0xE6, 0x32, 0x03, 0xDA, 0x0D,
0xE4, 0x02, 0x78, 0xB3, 0xA5, 0x4F, 0x5D, 0xDC, 0x69, 0x75, 0xFA, 0x04, 0xF7, 0x49, 0x84, 0x9E,
0x1A, 0x62, 0x59, 0x5A, 0x9F, 0x63, 0x0B, 0x07, 0x95, 0x91, 0x3D, 0xE0, 0x15, 0x3E, 0x3A, 0xAC,
0x38, 0x8C, 0x45, 0xFB, 0x9D, 0x85, 0x0C, 0xFE, 0x91, 0x35, 0x41, 0xD6, 0xC0, 0x83, 0x98, 0xF2,
0xC8, 0x83, 0x32, 0xA8, 0x2F, 0xDF, 0x00, 0x28, 0x1D, 0x62, 0xFC, 0xDC, 0x4F, 0xE7, 0xE4, 0x6A,
0xE9, 0x0C, 0x51, 0xC5, 0xC8, 0x06, 0xB4, 0x11, 0x64, 0xE3, 0x3A, 0xB9, 0x2C, 0x96, 0x86, 0x2E,
0x06, 0x8B, 0x0C, 0x16, 0xC0, 0x99, 0x90, 0xB8, 0x38, 0x1A, 0x00, 0xDA, 0x79, 0x15, 0xB6, 0x7F,
0xE4, 0xA2, 0x0F, 0x59, 0x9B, 0x0F, 0x1B, 0x6D, 0x48, 0x19, 0x13, 0xC7, 0xB9, 0x53, 0x8C, 0xEE,
0x63, 0x91, 0x44, 0xF4, 0x15, 0x61, 0xBA, 0x92, 0xE4, 0xFE, 0x75, 0x1D, 0x1E, 0x24, 0x2C, 0xD8,
0x8F, 0x51, 0xD6, 0x95, 0x51, 0x98, 0x87, 0x13, 0x6A, 0x7C, 0x15, 0xAA, 0xBD, 0x7B, 0x40, 0x04,
0x49, 0x22, 0x01, 0x41, 0x30, 0xA9, 0x1F, 0x17, 0x0F, 0x66, 0xCC, 0xB3, 0xC1, 0x39, 0x46, 0x3A,
0x7E, 0x90, 0x9A, 0x37, 0xAA, 0x86, 0x3F, 0xB2, 0x78, 0x05, 0xFC, 0x97, 0x31, 0xC0, 0x9C, 0x8C,
0x79, 0x06, 0x7E, 0x79, 0x93, 0x0A, 0x40, 0x65, 0x46, 0xB2, 0x4C, 0x9A, 0x62, 0x9B, 0x26, 0xC2,
0xCE, 0x2A, 0x4B, 0xE4, 0x8F, 0x58, 0x9A, 0x37, 0x5F, 0xEB, 0x73, 0x1F, 0xC4, 0xAB, 0x22, 0x5C,
0x11, 0x84, 0x8C, 0xF8, 0x9E, 0x29, 0x1F, 0xB2, 0x71, 0x33, 0x97, 0x0C, 0x06, 0x36, 0x18, 0x47,
0x4A, 0x89, 0x28, 0x01, 0xED, 0xD6, 0x8F, 0x54, 0x69, 0x8C, 0x5E, 0x5B, 0x50, 0x67, 0x46, 0xF6,
0x76, 0x5A, 0x6F, 0x7F, 0x12, 0x25, 0xDE, 0xA4, 0xDA, 0x11, 0x40, 0xFE, 0xB6, 0x0F, 0x65, 0x07,
0x45, 0x24, 0x1C, 0x69, 0x36, 0x95, 0x88, 0x3D, 0xCB, 0x21, 0xE6, 0xFB, 0xFE, 0xFB, 0xB8, 0x5A,
0x29, 0x91, 0x94, 0x80, 0x36, 0xA5, 0x2B, 0x5D
};
#include “cryptopp/des.h”
#include “cryptopp/blowfish.h”
#include “cryptopp/idea.h”
#include “cryptopp/rc2.h”
#include “cryptopp/rc5.h”
#include “cryptopp/cast.h”
#include “cryptopp/safer.h”
#include “cryptopp/skipjack.h”
#include “cryptopp/tea.h”
#include “cryptopp/gost.h”
#include “cryptopp/shark.h”
#include “cryptopp/modes.h”
#include “cryptopp/panama.h”
#include “cryptopp/sosemanuk.h”
#include “cryptopp/salsa.h”
#include “cryptopp/arc4.h”
#include “cryptopp/seal.h”
#include “cryptopp/wake.h”
#include “cryptopp/md5.h”
#include “cryptopp/sha.h”
#include “cryptopp/sha3.h”
#include “cryptopp/tiger.h”
#include “cryptopp/whrlpool.h”
#include “cryptopp/ripemd.h”
using namespace CryptoPP;
vector<HashTransformation*> Hashes {
new MD5,
new SHA1,
new SHA224,
new SHA256,
new SHA384,
new SHA512,
new SHA3(0x1C),
new SHA3(0x20),
new SHA3(0x30),
new SHA3(0x40),
new Tiger,
new Whirlpool,
new RIPEMD128,
new RIPEMD160,
new RIPEMD256,
new RIPEMD320,
};
bool my_isalnum(char c)
{
return (c >= ‘0’ && c <= ‘9’) || (c >= ‘a’ && c <= ‘z’) || (c >= ‘A’ && c <= ‘Z’);
}
char my_tolower(char c)
{
return c >= ‘A’ && c <= ‘Z’ ? ‘a’ + (c - ‘A’) : c;
}
char my_toupper(char c)
{
return c >= ‘a’ && c <= ‘z’ ? ‘A’ + (c - ‘a’) : c;
}
string MC(string Text, uint c)
{
switch©
{
case 1:
for (size_t i = 0; i < Text.size(); ++i)
Text[i] = my_tolower(Text[i]);
break;
case 2:
if (!Text.empty())
Text[0] = my_toupper(Text[0]);
for (size_t i = 1; i < Text.size(); ++i)
Text[i] = my_tolower(Text[i]);
break;
case 3:
for (size_t i = 0; i < Text.size(); ++i)
Text[i] = my_toupper(Text[i]);
break;
}
return Text;
}
double ShannonEntropy(string String)
{
if (String.empty())
return 0;
size_t Counts[0x100] {};
for (size_t i = 0; i < String.size(); ++i)
++Counts[(byte)String[i]];
double result = 0;
for (size_t i = 0; i < 0x100; ++i)
{
double frequency = (double)Counts[i] / String.size();
if (frequency)
result -= frequency * log2(frequency);
}
return result;
}
vector<array<BlockCipher*, 2>> BlockCiphers {
{{new DES::Encryption, new DES:
ecryption}},
{{new DES_EDE2::Encryption, new DES_EDE2:
ecryption}},
{{new DES_EDE3::Encryption, new DES_EDE3:
ecryption}},
{{new DES_XEX3::Encryption, new DES_XEX3:
ecryption}},
{{new Blowfish::Encryption, new Blowfish:
ecryption}},
{{new IDEA::Encryption, new IDEA:
ecryption}},
{{new RC2::Encryption, new RC2:
ecryption}},
{{new RC5::Encryption, new RC5:
ecryption}},
{{new CAST128::Encryption, new CAST128:
ecryption}},
{{new SAFER_K::Encryption, new SAFER_K:
ecryption}},
{{new SAFER_SK::Encryption, new SAFER_SK:
ecryption}},
{{new SKIPJACK::Encryption, new SKIPJACK:
ecryption}},
{{new TEA::Encryption, new TEA:
ecryption}},
{{new XTEA::Encryption, new XTEA:
ecryption}},
{{new GOST::Encryption, new GOST:
ecryption}},
{{new SHARK::Encryption, new SHARK:
ecryption}},
};
vector<pair<array<CipherModeBase*, 2>, bool>> Modes {
{{{new ECB_Mode_ExternalCipher::Encryption, new ECB_Mode_ExternalCipher:
ecryption}}, false},
{{{new CBC_Mode_ExternalCipher::Encryption, new CBC_Mode_ExternalCipher:
ecryption}}, false},
{{{new CBC_CTS_Mode_ExternalCipher::Encryption, new CBC_CTS_Mode_ExternalCipher:
ecryption}}, false},
{{{new CFB_Mode_ExternalCipher::Encryption, new CFB_Mode_ExternalCipher:
ecryption}}, true},
{{{new OFB_Mode_ExternalCipher::Encryption, new OFB_Mode_ExternalCipher:
ecryption}}, true},
{{{new CTR_Mode_ExternalCipher::Encryption, new CTR_Mode_ExternalCipher:
ecryption}}, true},
};
vector<SymmetricCipher*> SymmetricCiphers {
new PanamaCipher<>::Encryption,
new Sosemanuk::Encryption,
new Salsa20::Encryption,
new XSalsa20::Encryption,
new ARC4::Encryption,
new SEAL<>::Encryption,
new WAKE_OFB<>::Encryption,
};
string Decrypt(BlockCipher& Cipher, string const& Key, string const& Code, CipherModeBase& Mode, string const& IV)
{
size_t blockSize = 8;
assert(Cipher.BlockSize() == blockSize);
assert(Code.size() % blockSize == 0);
size_t keySize = Cipher.GetValidKeyLength(Key.size());
byte* pKey = (byte*)alloca(keySize);
memset(pKey, 0, keySize);
copy_n(Key.begin(), min(Key.size(), keySize), pKey);
Cipher.SetKey(pKey, keySize);
byte* pIV = (byte*)alloca(blockSize);
memset(pIV, 0, blockSize);
copy_n(IV.begin(), min(IV.size(), blockSize), pIV);
Mode.SetCipherWithIV(Cipher, pIV);
string Output;
Output.resize(Code.size());
Mode.ProcessData((byte*)Output.data(), (byte const*)Code.data(), Code.size());
return Output;
}
string Decrypt(SymmetricCipher& Cipher, string const& Key, string const& Code, string const& IV)
{
size_t keySize = Cipher.GetValidKeyLength(Key.size());
byte* pKey = (byte*)alloca(keySize);
memset(pKey, 0, keySize);
copy_n(Key.begin(), min(Key.size(), keySize), pKey);
size_t IVSize = Cipher.IVSize();
byte* pIV = (byte*)alloca(IVSize);
memset(pIV, 0, IVSize);
copy_n(IV.begin(), min(IV.size(), IVSize), pIV);
if (IVSize)
Cipher.SetKeyWithIV(pKey, keySize, pIV);
else
Cipher.SetKey(pKey, keySize);
string Output;
Output.resize(Code.size());
Cipher.ProcessData((byte*)Output.data(), (byte const*)Code.data(), Code.size());
return Output;
}
int main(int argc, wchar_t* argv[])
{
vector Phrases {
“”,
“\x10\x01\x08\x51\x39\x14\x09\x14”,
“BenalohPaillier”,
“CohenPaillier”,
“JoshPascal”,
“GoldwasserMicali”,
“Goldwasser-Micali”,
“Benaloh”,
“Paillier”,
“HomomorphicEncryption”,
“HomomorphicCryptosystem”,
“HomomorphicCryptosystems”,
“Niobium”,
“Niobium5”,
“NiobiumV”,
“NiobiumFive”,
“NiobiumPentachloride”,
“Terminal”,
“Abortive”,
“ThEpIzZaIsaLiE”,
“Halos”,
“HalosProject”,
“HalosAI”,
“TempusOmniaRevelant”,
“BMRF”,
“BMRF.us”,
“terminal.bmrf.us”,
“DALsystems”,
“DALsystems.com”,
“1.192.12.156”,
“1.192.12.156:2828”
“BlackMesaResearchFacility”,
“congratulationsyouwonthePIZZA”,
“CongratulationsYouWonThePIZZA”,
“CongratulationsYouWonThePizza”,
“Pizza”,
“Pizzas”,
“GiordanoBruno”,
“Kryptos”,
“KryptosStatue”,
“BonAmi”,
“KONami”,
“KONamiCode”,
“KonamiCode”,
“DrHorn”,
“DrWelsh”,
“DrJWelsh”,
“DrMontero”,
“DrStone”,
“DrBottomley”,
“DrJunek”,
“DrForeman”,
“DrMarcel”,
“VoxpopulivoxDei”,
“VoxPopuliVoxDei”,
“YouShouldBringPizzas”,
“DantesInferno”,
“Dante’sInferno”,
“Nimrod”,
“SuperbusViaInscientae”,
“StarTrek”,
“GrilledPizza”,
“StormSeeker”,
“TheStormSeeker”,
“Anthony”,
“Biodome”,
“LaserOptronicLinearInducerCannon”,
“AcceleratedLeptonOptronicLinearityCannon”,
“AcceleratedLeptonOptronicLinearCannon”,
“LeptonOptronicLinearityCannon”,
“Accelerated”,
};
double lowest = 8;
for (size_t c = 0; c < 0x10; ++c)
{
cout << ((double)c / 0x10) << "\n";
for (auto Key : Phrases)
for (auto IV : Phrases)
for (auto pCipher : BlockCiphers)
for (auto pMode : Modes)
for (auto pHash : Hashes)
{
string Phrase = MC(Key, c % 4);
string Key;
Key.resize(pHash->DigestSize());
pHash->CalculateDigest((byte*)Key.data(), (byte const*)Phrase.data(), Phrase.size());
string Result = Decrypt(*pCipher[pMode.second ? 0 : 1], Key, string((char*)Code, sizeof(Code)), *pMode.first[1], MC(IV, c / 4));
double entropy = ShannonEntropy(Result);
if (entropy < lowest)
lowest = entropy;
if (entropy < 7)
{
cout << entropy << "\n";
cout << pCipher[0]->AlgorithmName() << ", " << MC(Phrase, c % 4) << ", " << pMode.first[0]->AlgorithmName() << ", " << MC(IV, c / 4) << ", " << pHash->AlgorithmName() << "\n";
cout << "\n";
}
}
}
for (size_t c = 0; c < 0x10; ++c)
for (auto Key : Phrases)
for (auto IV : Phrases)
for (auto pCipher : SymmetricCiphers)
for (auto pHash : Hashes)
{
string Phrase = MC(Key, c % 4);
string Key;
Key.resize(pHash->DigestSize());
pHash->CalculateDigest((byte*)Key.data(), (byte const*)Phrase.data(), Phrase.size());
string Result = Decrypt(*pCipher, Key, string((char*)Code, sizeof(Code)), MC(IV, c / 4));
double entropy = ShannonEntropy(Result);
if (entropy < lowest)
lowest = entropy;
if (entropy < 7)
{
cout << entropy << "\n";
cout << pCipher->AlgorithmName() << ", " << MC(Phrase, c % 4) << ", " << MC(IV, c / 4) << ", " << pHash->AlgorithmName() << "\n";
cout << "\n";
}
}
cout << lowest << "\n";
return 0;
}[/code]
Note that this is in C++11. Also it’s the version with password hashes, one needs to remove the hash loops and key hashing lines in order to test with plaintext passwords.
Zero IV is included too, under the empty string. My decrypt routine accepts any size keys and IVs and pads them with zeros or truncates them.