diff options
author | Samuel Lidén Borell <samuel@kodafritt.se> | 2014-12-09 18:14:52 +0100 |
---|---|---|
committer | Samuel Lidén Borell <samuel@kodafritt.se> | 2014-12-09 20:56:46 +0100 |
commit | 6fc06175a146a93d3a2715e6782d4e26ab90a60f (patch) | |
tree | c7bb5b7e6090833f42ce920cd7ca65cc04e4ae1c | |
download | aesscan-main.tar.gz aesscan-main.tar.bz2 aesscan-main.zip |
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | LICENSE | 21 | ||||
-rw-r--r-- | Makefile | 16 | ||||
-rw-r--r-- | README | 45 | ||||
-rw-r--r-- | aesscan.c | 496 | ||||
-rwxr-xr-x | test/encrypt.sh | 10 | ||||
-rw-r--r-- | test/encrypted-txt-1.bin | bin | 0 -> 880 bytes | |||
-rw-r--r-- | test/encrypted-txt-2.bin | bin | 0 -> 944 bytes | |||
-rw-r--r-- | test/encrypted-txt-3.bin | bin | 0 -> 736 bytes | |||
-rw-r--r-- | test/encrypted-txt-with-iv-1.bin | bin | 0 -> 896 bytes | |||
-rw-r--r-- | test/encrypted-txt-with-iv-2.bin | bin | 0 -> 960 bytes | |||
-rw-r--r-- | test/encrypted-txt-with-iv-3.bin | bin | 0 -> 752 bytes | |||
-rw-r--r-- | test/encrypted-txt-with-iv.bin | 2 | ||||
-rw-r--r-- | test/encrypted-txt.bin | 1 | ||||
-rw-r--r-- | test/key.bin | 2 | ||||
-rw-r--r-- | test/keyandjunk.bin | bin | 0 -> 137088 bytes | |||
-rw-r--r-- | test/plaintext-1.txt | 12 | ||||
-rw-r--r-- | test/plaintext-2.txt | 11 | ||||
-rw-r--r-- | test/plaintext-3.txt | 8 | ||||
-rw-r--r-- | test/plaintext.txt | 3 |
20 files changed, 629 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44746e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.o +aesscan @@ -0,0 +1,21 @@ + +Copyright © 2014 Samuel Lidén Borell <samuel@kodafritt.se> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c93324b --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +CFLAGS += -Wall -Wextra -ansi +LDFLAGS += -lnettle + +all: aesscan + +aesscan: aesscan.o + +clean: + -rm -f aesscan aesscan.o + +# Should show "109992: found key (decrypted data = 4 text, 0 binary)" +test: aesscan + ./aesscan -s test/keyandjunk.bin test/encrypted-txt-with-iv.bin test/encrypted-txt-with-iv-1.bin test/encrypted-txt-with-iv-2.bin test/encrypted-txt-with-iv-3.bin + + +.PHONY: all clean test @@ -0,0 +1,45 @@ +AESScan +------- + +This is a command line utility to search binary data for possible AES keys. +You will need one or more ciphertexts encrypted using the key that is +suspected to appear in the binary file. The ciphertexts are used to attempt +decryption, and check if the resulting plaintext makes any sense. The +plaintext is assumed to contain either a large number of zero bytes (typical +for binary data) or a very small number of uncommon control characters +(typical for text files). So it's not possible to use this tool on random data +that has been encrypted, or data that has been encrypted multiple times. + +The command line syntax is: + + aesscan -s binary.bin [options] ciphertext1.bin ciphertext2.bin ... + +Where binary.bin is the file to search for keys in. Supported options are: + + -c CIPHER Set the cipher to use: + 0 AES128 with CBC (default) + 1 AES128 with ECB + 2 AES256 with CBC + 3 AES256 with ECB + -p PADDING Set the padding to use: + 0 PKCS#5 (default) + 1 Simply throw away the last block + 2 No padding + -l LEN Try to decrypt only up to LEN bytes in the FILES + -o OFFSET Start from the given byte offset in the FILES + +The -o and -l options are parsed from left to right. An -o or -l option must +occur before the ciphertext file(s) it should to apply to. + +AES is typically used with a block mode and a padding. CBC and PKCS#7 +is the most common block mode and padding, so these are the defaults. +When the padding type is unknown, it is useful to use "throw away" option +(number 1) which will simply skip the last encrypted block. This option will +obviously only work if the data is more than 16 bytes, which is the block +size of AES (regardless of key size). + +For block modes other than ECB, this tool will assume that the first 16 bytes +is the Initialization Vector (IV) for the following data. This is the most +common way of encoding encrypted AES data. + + diff --git a/aesscan.c b/aesscan.c new file mode 100644 index 0000000..b9c9e95 --- /dev/null +++ b/aesscan.c @@ -0,0 +1,496 @@ +/* + + aesscan.c -- Utility to scan for AES keys in binaries + + Copyright © 2014 Samuel Lidén Borell <samuel@kodafritt.se> + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + +*/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <nettle/aes.h> +#include <nettle/cbc.h> + +#define READSIZE 1024 + +struct fileentry { + char *name; + long datalen; + unsigned char *data; +}; + +enum ciphermode { + AES128_CBC = 0, + AES128_ECB, + AES256_CBC, + AES256_ECB +}; + +static const char ciphermodes[][11] = { + "AES128_CBC", + "AES128_ECB", + "AES256_CBC", + "AES256_ECB" +}; + + +static const int cipher_iv_size[] = { + AES_BLOCK_SIZE, + 0, + AES_BLOCK_SIZE, + 0 +}; + +static const size_t cipher_key_size[] = { + 128/8, /* TODO upgrade libnettle and use AES128_KEY_SIZE */ + 128/8, + 256/8, + 256/8 +}; + +enum padding { + PKCS7, + THROW_AWAY, /* throw away last block */ + NO_PADDING +}; + +static const char paddings[][11] = { + "PKCS#7", + "THROW_AWAY", + "NONE" +}; + + +static long offset; +static long maxlength; +static long numfiles; +static struct fileentry *files; +static char *scanfilename; +static FILE *scanfile; +static unsigned char *decryptbuff; +static enum ciphermode ciphermode; +static enum padding padding; + +static union { + struct aes_ctx aesctx; + /*struct CBC_CTX(struct aes_ctx, 128/8) aes128cbc;*/ +} keyctx; + + +enum typeofdata { + JUNK = 0, + TEXT = 1, + BINARY = 2 +}; + +/* + No strange control characters = OK, probably text + High number of zeros = OK, probably binary data +*/ +enum typeofdata checkdata(const unsigned char *data, long len) +{ + long numzeros = 0; + long numcontrol = 0; + float rzero, rctrl; + const unsigned char *p = data; + const unsigned char *end = data+len; + + int i; + char padsize = end[-1]; + if (padding == PKCS7) { + if (padsize > AES_BLOCK_SIZE || padsize < 0) { + return JUNK; + } + for (i = 0; i < padsize; i++) { + if (end <= p || *--end != padsize) return JUNK; + } + } else if (padding == THROW_AWAY) { + end -= AES_BLOCK_SIZE; + } + + while (p < end) { + unsigned char c = *(p++); + if (c == '\0') { + numzeros++; + } else if (c >= '\x01' && c <= '\x1F' && + c != '\x09' && c != '\x08' && c != '\x0A' && c != '\x0D') { + numcontrol++; + } + } + + rzero = (float)numzeros / (float)len; + rctrl = (float)numcontrol / (float)len; + + if (rzero >= 0.02) { /* >> 1/256 */ + return BINARY; + } else if (rctrl <= 0.03) { /* << (32-4) / 256 */ + return TEXT; + } else if (padding == PKCS7 && padsize >= 4) { + return BINARY; + } else { + return JUNK; + } +} + +void decrypt(unsigned char *encrypted, long len, const unsigned char *key, + unsigned char *decrypted) +{ + unsigned char iv[AES_BLOCK_SIZE]; + /* TODO use nettle-meta.h */ + switch (ciphermode) { + case AES128_CBC: + if (len < AES_BLOCK_SIZE) { abort(); } + memcpy(iv, encrypted, AES_BLOCK_SIZE); + aes_set_decrypt_key(&keyctx.aesctx, 128/8, key); + cbc_decrypt(&keyctx.aesctx, (nettle_crypt_func *)aes_decrypt, AES_BLOCK_SIZE, iv, + len-AES_BLOCK_SIZE, decrypted, encrypted+AES_BLOCK_SIZE); + break; + case AES128_ECB: + aes_set_decrypt_key(&keyctx.aesctx, 128/8, key); + aes_decrypt(&keyctx.aesctx, len, decrypted, encrypted); + break; + case AES256_CBC: + if (len < AES_BLOCK_SIZE) { abort(); } + memcpy(iv, encrypted, AES_BLOCK_SIZE); + aes_set_decrypt_key(&keyctx.aesctx, 256/8, key); + cbc_decrypt(&keyctx.aesctx, (nettle_crypt_func *)aes_decrypt, AES_BLOCK_SIZE, iv, + len-AES_BLOCK_SIZE, decrypted, encrypted+AES_BLOCK_SIZE); + break; + case AES256_ECB: + aes_set_decrypt_key(&keyctx.aesctx, 256/8, key); + aes_decrypt(&keyctx.aesctx, len, decrypted, encrypted); + break; + default: + abort(); + } + /*putchar(key[128/8-1]);*/ +} + +int try_decrypt(long scan_offset, unsigned char *key) +{ + long files_text = 0, files_bin = 0; + long i; + + for (i = 0; i < numfiles; i++) { + const struct fileentry *entry = &files[i]; + enum typeofdata result; + const long decryptlen = entry->datalen - cipher_iv_size[ciphermode]; + +/*if (*key == 0x4B && key[1] == 0x45 && key[2] == 0x59) { +fprintf(stderr, "found key at %ld\n", scan_offset); +fprintf(stderr, "file = %hhx %hhx %hhx %hhx\n", entry->data[0], entry->data[1], entry->data[2], entry->data[3]); +}*/ + decrypt(entry->data, entry->datalen, key, decryptbuff); +/*if (*key == 0x4B && key[1] == 0x45 && key[2] == 0x59) { +fprintf(stderr, "data = %.*s\n", decryptlen, decryptbuff); +}*/ + +/*result = 0; +if (*key == 0x4B && key[1] == 0x45 && key[2] == 0x59) {*/ + result = checkdata(decryptbuff, decryptlen); +/*fprintf(stderr, "result = %d\n", result); +}*/ + + if (result == JUNK) return 0; + + if (result == BINARY) files_bin++; + else files_text++; + } + + printf("%ld: found key (decrypted data = %ld text, %ld binary)\n", + scan_offset, files_text, files_bin); + return 0; +} + +void do_scan_file() +{ + unsigned char keybuff[2*READSIZE]; + unsigned long scan_offset = 0; + const unsigned long keysize = cipher_key_size[ciphermode]; + + size_t numbytes = fread(keybuff, 1, READSIZE, scanfile); + if (numbytes != READSIZE && ferror(scanfile)) { + perror("scan file too short"); + exit(1); + } + + /* Scan the first half of the buffer and move in more data. + This is done so we can handle keys that overlap a READSIZE + boundary. */ + while (!feof(scanfile)) { + unsigned long keyoffs = 0; + int nonzeros = keysize; + + if ((scan_offset & 0xFFFFFL) == 0) { + fprintf(stderr, "Scanned %ld bytes\n", scan_offset); + } + + numbytes += fread(keybuff+READSIZE, 1, READSIZE, scanfile); + while (numbytes > READSIZE) { + if (keybuff[keyoffs+keysize]) { + nonzeros = keysize; + } + + if (nonzeros) { + try_decrypt(scan_offset, &keybuff[keyoffs]); + } + numbytes--; + scan_offset++; + keyoffs++; + if (nonzeros) nonzeros--; + } + memcpy(keybuff, keybuff+READSIZE, READSIZE); + } + + /* Scan the remaining data */ + { + unsigned long keyoffs = 0; + while (numbytes > keysize) { + try_decrypt(scan_offset, &keybuff[keyoffs]); + numbytes--; + scan_offset++; + keyoffs++; + } + fprintf(stderr, "Scanned %ld bytes\n", scan_offset); + } +} + +void show_usage(const char *arg0) +{ + printf("usage: %s -s FILE_TO_SCAN [-o OFFSET] [-l LEN] FILES...\n" + "\n" + "Tries to decrypt the given FILES with AES-128/256 using all 128/256-bit\n" + "substrings in FILE_TO_SCAN.\n" + "\n" + "Options:\n" + " -c CIPHER Set the cipher to use:\n" + " 0 AES128 with CBC (default)\n" + " 1 AES128 with ECB\n" + " 2 AES256 with CBC\n" + " 3 AES256 with ECB\n" + " -p PADDING Set the padding to use:\n" + " 0 PKCS#5 (default)\n" + " 1 Simply throw away the last block\n" + " 2 No padding\n" + " -l LEN Try to decrypt only up to LEN bytes in the FILES\n" + " -o OFFSET Start from the given byte offset in the FILES\n" + "\n" + "Note: The -o and -l options are parsed from left to right. An -o\n" + "or -l option must occur before the file(s) it should to apply to.\n" + "\n", + arg0); +} + +long get_num(int argc, char **argv, int *idxp) +{ + int i = *idxp; + long value; + char *s, *endp; + + if (i+1 >= argc) { + fprintf(stderr, "%s: option requires an argument\n", argv[i]); + exit(2); + } + + s = argv[i+1]; + value = strtol(s, &endp, 10); + if (*s == '\0' || *endp != '\0' || value < 0) { + fprintf(stderr, "%s: invalid number\n", s); + exit(2); + } + + *idxp = i+1; + return value; +} + +char *get_str(int argc, char **argv, int *idxp) +{ + int i = *idxp; + + if (i+1 >= argc) { + fprintf(stderr, "%s: option requires an argument\n", argv[i]); + exit(2); + } + + *idxp = i+1; + return argv[i+1]; +} + +int main(int argc, char **argv) +{ + int parsing_opts = 1, error = 0; + int i; + long maxdatalen; + for (i = 1; i < argc; i++) { + char *const arg = argv[i]; + if (arg[0] == '-' && parsing_opts) { + /* Option */ + if (arg[1] == '-' && arg[2] == '\0') { + /* "--" = stop parsing arguments */ + parsing_opts = 0; + continue; + } + if (arg[1] != '\0' && arg[2] == '\0') { + switch (arg[1]) { + case 'c': /*{ + const char *s = get_str(argc, argv, &i); + if (strcmp + break; }*/ + ciphermode = get_num(argc, argv, &i); + if (ciphermode > AES256_ECB) { + fprintf(stderr, "%s: invalid cipher type %d\n", + argv[0], ciphermode); + error = 1; + } + break; + case 'h': + show_usage(argv[0]); + return 0; + case 'l': + maxlength = get_num(argc, argv, &i); + break; + case 'o': + offset = get_num(argc, argv, &i); + break; + case 'p': + padding = get_num(argc, argv, &i); + if (padding > NO_PADDING) { + fprintf(stderr, "%s: invalid paddig type %d\n", + argv[0], padding); + error = 1; + } + break; + case 's': + scanfilename = get_str(argc, argv, &i); + break; + } + } + } else { + /* Filename */ + unsigned char *data; + long datalen; + struct fileentry *entry; + FILE *file = fopen(arg, "rb"); + if (!file) { + perror(arg); + error = 1; + continue; + } + + if (offset) { + if (fseek(file, offset, SEEK_SET) == -1) { + perror(arg); + exit(1); + } + } + + if (!maxlength) { + /* Read the whole file */ + if (fseek(file, 0, SEEK_END) == -1) { + perror(arg); + exit(1); + } + + datalen = ftell(file) - offset; + if (datalen < 0) { + perror("ftell"); + exit(1); + } + + data = malloc(datalen); + if (!data) { + perror("allocating memory for file"); + exit(1); + } + + if (fseek(file, offset, SEEK_SET) == -1) { + perror(arg); + exit(1); + } + } + + if (fread(data, 1, datalen, file) != (size_t)datalen) { + perror(arg); + exit(1); + } + + fclose(file); + + if (datalen == 0) { + fprintf(stderr, "%s: File is empty\n", arg); + exit(1); + } + + numfiles++; + files = realloc(files, sizeof(struct fileentry)*numfiles); + if (!files) { + perror("realloc"); + exit(1); + } + entry = &files[numfiles-1]; + entry->name = arg; + entry->data = data; + entry->datalen = datalen; + } + } + + if (error) { + return 1; + } + + if (!numfiles) { + fprintf(stderr, "%s: no files specified\n", argv[0]); + show_usage(argv[0]); + return 2; + } + + if (!scanfilename) { + fprintf(stderr, "%s: no scan file specified\n", argv[0]); + return 2; + } + + /* Allocate buffer for decryption */ + maxdatalen = 0; + for (i = 0; i < numfiles; i++) { + if (files[i].datalen > maxdatalen) { + maxdatalen = files[i].datalen; + } + } + decryptbuff = malloc(maxdatalen); + + fprintf(stderr, "Using %s cipher and mode, with padding %s\n", + ciphermodes[ciphermode], paddings[padding]); + + /* Start scanning the file for keys */ + scanfile = fopen(scanfilename, "rb"); + if (!scanfile) { + perror(scanfilename); + exit(1); + } + + do_scan_file(); + + fclose(scanfile); + + return 0; +} + diff --git a/test/encrypt.sh b/test/encrypt.sh new file mode 100755 index 0000000..1c8753a --- /dev/null +++ b/test/encrypt.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +key=4B4559030405060708090A0B0C0D0E0F + +iv=495612131415161718191A1B1C1D1E1F +num=1 + +openssl enc -aes-128-cbc -e -in plaintext-$num.txt -out encrypted-txt-$num.bin -iv $iv -K $key +echo $iv | xxd -ps -r > encrypted-txt-with-iv-$num.bin +cat encrypted-txt-$num.bin >> encrypted-txt-with-iv-$num.bin diff --git a/test/encrypted-txt-1.bin b/test/encrypted-txt-1.bin Binary files differnew file mode 100644 index 0000000..faf8ade --- /dev/null +++ b/test/encrypted-txt-1.bin diff --git a/test/encrypted-txt-2.bin b/test/encrypted-txt-2.bin Binary files differnew file mode 100644 index 0000000..7243e66 --- /dev/null +++ b/test/encrypted-txt-2.bin diff --git a/test/encrypted-txt-3.bin b/test/encrypted-txt-3.bin Binary files differnew file mode 100644 index 0000000..6770364 --- /dev/null +++ b/test/encrypted-txt-3.bin diff --git a/test/encrypted-txt-with-iv-1.bin b/test/encrypted-txt-with-iv-1.bin Binary files differnew file mode 100644 index 0000000..f0dc33b --- /dev/null +++ b/test/encrypted-txt-with-iv-1.bin diff --git a/test/encrypted-txt-with-iv-2.bin b/test/encrypted-txt-with-iv-2.bin Binary files differnew file mode 100644 index 0000000..9584632 --- /dev/null +++ b/test/encrypted-txt-with-iv-2.bin diff --git a/test/encrypted-txt-with-iv-3.bin b/test/encrypted-txt-with-iv-3.bin Binary files differnew file mode 100644 index 0000000..133b959 --- /dev/null +++ b/test/encrypted-txt-with-iv-3.bin diff --git a/test/encrypted-txt-with-iv.bin b/test/encrypted-txt-with-iv.bin new file mode 100644 index 0000000..5382c1e --- /dev/null +++ b/test/encrypted-txt-with-iv.bin @@ -0,0 +1,2 @@ +IV +
顐DA~"︍VʹΞHY92@fk@YA[TH:5P&y[98<i!_HBXB}}mHÙזaw@8r㶡
\ No newline at end of file diff --git a/test/encrypted-txt.bin b/test/encrypted-txt.bin new file mode 100644 index 0000000..432a764 --- /dev/null +++ b/test/encrypted-txt.bin @@ -0,0 +1 @@ +顐DA~"︍VʹΞHY92@fk@YA[TH:5P&y[98<i!_HBXB}}mHÙזaw@8r㶡
\ No newline at end of file diff --git a/test/key.bin b/test/key.bin new file mode 100644 index 0000000..0364907 --- /dev/null +++ b/test/key.bin @@ -0,0 +1,2 @@ +KEY +
\ No newline at end of file diff --git a/test/keyandjunk.bin b/test/keyandjunk.bin Binary files differnew file mode 100644 index 0000000..1d50def --- /dev/null +++ b/test/keyandjunk.bin diff --git a/test/plaintext-1.txt b/test/plaintext-1.txt new file mode 100644 index 0000000..7ad3603 --- /dev/null +++ b/test/plaintext-1.txt @@ -0,0 +1,12 @@ +Hej blablabla +sdfdsdsfdsfsdhjfsdfjksd jsdfsd sdfjksd hsdkhdjskdsjkf jksakrwiczjhkfhdkdkfdfd +sdf dslfjd lkjsdlkfjsdlkrdjfldsjf ilsdjldskdsfj dsk jkfjfdkfdjskdsjfksjksdfj +sd fkfjdslkjlksdj fld jfkldj lksdfjlksdjf lkdj flkdjflkdj flkdjlkjlkfjldk + kdjflkdsjkflsdjdslk fjlkdsfj lkdsj kdsjfkldsjlfkj dlkfjdslkf jdslk jfdslkjfd + dkfdlkjf lkjlkdfjlkjfdkljlkdsfjslkdfjlksdjkljdskldj flkdsj lkdjklfdjlkdfd jllk + kldsfj sdklfj lksdj flksdj flkdsjf klsdj fklj lkdj klfjsdlkfjskdl jkdlfj l +dskljdslkf jlsdkfj lkdj kjd lkfdj flkdj flksdj klj dlkj lkj lkfjd lkd jlkfdj +ksdjfkldsjf lkdslfdslk djsklfj dlksdj k jsljfkj fklfjslkf sj lksj kljfsdkljlk +w oit wifjewlifjeljesseli jlisej leijli jliesjfliejliejf liejflis ifs jilse +mv,f ,vnkvkz z zv,nzv,nzsj,vnd,z vnzdfzsd,n zis iej fwjfijweifjls sljf l jflse fjl + ilsjifjlew ifjlwj93fjl4fo slfjslf kdf lsdfj dlsifjiwljfo9w3fjsliejliesjlf diff --git a/test/plaintext-2.txt b/test/plaintext-2.txt new file mode 100644 index 0000000..1b1c63c --- /dev/null +++ b/test/plaintext-2.txt @@ -0,0 +1,11 @@ +kvojidsfmkaJIVKLAGKDSFL SJFLDSJFLDSKOSDKFLSDKLDSFKLDSKFLDSK Lkllf dlk df lsdk lfk +sdlk flksjfLJlsdf klsd flkdF LKD KFJLSDJLKSDJF LSKDjdlkjdlk fjsklfjdkf jdkldjflsefs +sdlkjf sdlkjf lior3lwifjwl9rw3lorijsflisjkx,nvkjzljzlflzeivijlizfkszkjkzjjscljik hkseh fk +sd fdsfoijsif ejilejrifdzjkiej lifhkifheihjhke zil esf idf difjdslifj sdfdksjfsfsddfd +ior3ijowejihujoirweilse5945943085435 3453435 43543545435 34543 345435435435436436 +434593580284795724857943757439574389578439 789437 89437598 73895743985798457435 +43859435843850934890 83904830498590389038904389058908908b09 890 843908904 940859085 +438 90850984305984359 89304 8530958 9038590348 5903485903485 904385 90348590348 905830 +98508593 8340958 3049 85904385 9034859034859043859085094389504385908435904385049350 +439058904843058 93048 5903 8903458 9043 8903485 904385 49038 59038 908 90438 590438 50 +stir tjlirjtlirjtilwetiowutoiueoituwe oiruweoiuweioruiowrui ou iouweoiuroiwe uoieru diff --git a/test/plaintext-3.txt b/test/plaintext-3.txt new file mode 100644 index 0000000..6021538 --- /dev/null +++ b/test/plaintext-3.txt @@ -0,0 +1,8 @@ +jrilejd fklsjdlJLIJILJESLIFJSLIFsdfkofksdkldsldflksdklsdjkljklsdjlkfjsdlkfsjdfkljlkslksdj +dsf sdjklfjsdkljsdkl jfdlsjfklsdfj sd jfklsdjfkdsjk lsdjlkdsjflkdj kldsj kldsjfkldsjfkldsj +sdfj dlskjfdskl jfdslkjfdkljfdsklfjsdlkjfsdkljslkfjsdkljfdslk jdslk jfsdlkjfsdlkfjsdlkjgds +ewrt532532532 23423 423423423 523tk lklgfkljfdklgj fdklgjfdlkjgkjfidjocjiovjxoivjixocvjo +oicxjvoixcjviocicoxioxcuvcoiuxoiuvoicxuvoixuoicuvxcoiuvoixcuvioxc ucio vuoi ucoi uvoicxu o +iuvoi cxuviocu voixcuvoixcu voiuvioxcuviocuvoifeoiduou3ofieuzouoi ueoiucoi3jceljilfjcielo +kjgijweofjsielfjlijlkfosekfelskflisejflijelsjielsfjielieilejoeriqoriqwiwqriqwpowqporwqpo +xzcmzxbxzmvxznmvzxn zxnmnmvnmnmzxxzcxzczxczxcvdsvreofdijcnvmgoriuhfnjet9prkfjirit4woiejf diff --git a/test/plaintext.txt b/test/plaintext.txt new file mode 100644 index 0000000..4f19b42 --- /dev/null +++ b/test/plaintext.txt @@ -0,0 +1,3 @@ +Hello, this is a test file. Bla bla bla. 123456789 bla bla bla bla abcdefghijklmnopqrstuvwxyz +Bla bla bla bla bla. +Test test test test test test. |