/// <summary> /// Implement a repeating key XOR for the given input string /// </summary> /// <param name="input"></param> /// <param name="key"></param> /// <returns></returns> public string DoChallenge05(string input, string key) { RepeatingKeyXOR encryptor = new RepeatingKeyXOR(); return(encryptor.EncryptInputWithKey(input, key)); }
public virtual void SetUp() { _encryptor = new RepeatingKeyXOR(new FixedXOR()); }
/// <summary> /// /// </summary> /// <returns></returns> public string DoChallenge06() { //Get the byte array out of the encrypted data byte[] encryptedData = Convert.FromBase64String(base64EncryptedData); int lowestKeySize = RepeatingKeyXOR.FindKeySize_CopyFromInternet(encryptedData); // //Now the encryption key's length is probably known -- lowestKeySize // int numBlocksNeeded = (int)Math.Ceiling((double)encryptedData.Length / (double)lowestKeySize); //Break up the source into blocks of this size byte[][] blocks = new byte[numBlocksNeeded][]; for (int i = 0; i < numBlocksNeeded; i++) { int blockLen = lowestKeySize; if (i == numBlocksNeeded - 1) { //special case for last block - it may be shorter blockLen = encryptedData.Length % lowestKeySize; } blocks[i] = new byte[blockLen]; Array.Copy(encryptedData, i * lowestKeySize, blocks[i], 0, blockLen); } // //Assuming we guessed the right key size, we now have a series of blocks that should each be decryptable with the full key // byte[][] transposed = new byte[lowestKeySize][]; //The first array is numBlocksNeeded arrays of lowestKeySize bytes. e.g. blocks[576][5] //The transposed array is the reverse -- lowestKeySize arrays of numBlocksNeeded bytes. e.g. blocks[5][576] int transposedBlockLength = numBlocksNeeded; //Initialize first for (int i = 0; i < lowestKeySize; i++) { transposed[i] = new byte[transposedBlockLength]; } for (int block = 0; block < numBlocksNeeded; block++) { for (int keyIndex = 0; keyIndex < lowestKeySize; keyIndex++) { //Bounds check for our possibly-truncated last block if (blocks[block].Length > keyIndex) { transposed[keyIndex][block] = blocks[block][keyIndex]; } } } // //We now have a new series of transposed blocks that are each decryptable by a single character // StringBuilder sb = new StringBuilder(); foreach (byte[] bytes in transposed) { SingleCharXORDecoder decoder = new SingleCharXORDecoder(); decoder.TestAllKeys(bytes); SingleCharXORResult result = decoder.BestResults; sb.Append(result.BestKey); } string encryptionKey = sb.ToString(); return(encryptionKey); }