Exemple #1
0
    def attemptCrack(self, ctext: str) -> List[CrackResult]:
        logger.debug(f"Trying ASCII shift cipher on {ctext}")

        logger.trace("Beginning cipheycore simple analysis")

        # Hand it off to the core
        analysis = self.cache.get_or_update(
            ctext,
            "cipheycore::simple_analysis",
            lambda: cipheycore.analyse_string(ctext),
        )
        logger.trace("Beginning cipheycore::caesar")
        possible_keys = cipheycore.caesar_crack(analysis, self.expected,
                                                self.group, self.p_value)

        n_candidates = len(possible_keys)
        logger.debug(f"ASCII shift returned {n_candidates} candidates")

        if n_candidates == 0:
            logger.trace("Filtering for better results")
            analysis = cipheycore.analyse_string(ctext, self.group)
            possible_keys = cipheycore.caesar_crack(analysis, self.expected,
                                                    self.group, self.p_value)

        candidates = []

        for candidate in possible_keys:
            logger.trace(
                f"Candidate {candidate.key} has prob {candidate.p_value}")
            translated = cipheycore.caesar_decrypt(ctext, candidate.key,
                                                   self.group)
            candidates.append(
                CrackResult(value=translated, key_info=candidate.key))

        return candidates
Exemple #2
0
    def attemptCrack(self, ctext: str) -> List[CrackResult]:
        logging.info("Trying vigenere cipher")
        # Convert it to lower case
        if self.lower:
            message = ctext.lower()
        else:
            message = ctext

        # Analysis must be done here, where we know the case for the cache
        if self.keysize is not None:
            return self.crackOne(
                message,
                self.cache.get_or_update(
                    ctext,
                    f"vigenere::{self.keysize}",
                    lambda: cipheycore.analyse_string(
                        message, self.keysize, self.group
                    ),
                ),
                ctext,
            )

        arrs = []
        likely_lens = self.cache.get_or_update(
            ctext,
            "vigenere::likely_lens",
            lambda: cipheycore.vigenere_likely_key_lens(
                message, self.expected, self.group
            ),
        )
        possible_lens = [i for i in likely_lens]
        possible_lens.sort(key=lambda i: i.p_value)
        logging.debug(f"Got possible lengths {[i.len for i in likely_lens]}")
        # TODO: work out length
        for i in possible_lens:
            arrs.extend(
                self.crackOne(
                    message,
                    self.cache.get_or_update(
                        ctext,
                        f"vigenere::{i.len}",
                        lambda: cipheycore.analyse_string(message, i.len, self.group),
                    ),
                    ctext,
                )
            )

        logging.info(f"Vigenere returned {len(arrs)} candidates")
        return arrs
Exemple #3
0
 def checkChi(self, text):
     if text is None:
         return False
     if type(text) is bytes:
         try:
             text = text.decode()
         except:
             return None
     """Checks to see if the Chi score is good
     if it is, it returns True
     Call this when you want to determine whether something is likely to be Chi or not
     
     Arguments:
         * text - the text you want to run a Chi Squared score on
     
     Outputs:
         * True - if it has a significantly lower chi squared score
         * False - if it doesn't have a significantly lower chi squared score
     """
     # runs after every chi squared to see if it's 1 significantly lower than averae
     # the or statement is bc if the program has just started I don't want it to ignore the
     # ones at the start
     analysis = cipheycore.analyse_string(text)
     chisq = cipheycore.chisq_test(analysis, self.language)
     logger.debug(f"Chi-squared p-value is {chisq}")
     return chisq > self.chiSquaredSignificanceThreshold
Exemple #4
0
 def plaintext_probability(self, translated: str) -> float:
     """
     Analyses the translated text and applies the chi squared test to see if it is a probable plaintext candidate
     Returns the probability of the chi-squared test.
     """
     analysis = cipheycore.analyse_string(translated)
     return cipheycore.chisq_test(analysis, self.expected)
Exemple #5
0
def cached_freq_analysis(ctext, config):
    base = config.objs.setdefault("cached_freq_analysis", ctext)
    res = base.get("cached_freq_analysis")
    if res is not None:
        return res

    base["cached_freq_analysis"] = cipheycore.analyse_string(ctext)
Exemple #6
0
    def attemptCrack(self, ctext: str) -> List[CrackResult]:
        logger.debug("Trying caesar cipher")
        # Convert it to lower case
        #
        # TODO: handle different alphabets
        if self.lower:
            message = ctext.lower()
        else:
            message = ctext

        logger.trace("Beginning cipheycore simple analysis")

        # Hand it off to the core
        analysis = self.cache.get_or_update(
            ctext,
            "cipheycore::simple_analysis",
            lambda: cipheycore.analyse_string(message),
        )
        logger.trace("Beginning cipheycore::caesar")
        possible_keys = cipheycore.caesar_crack(analysis, self.expected,
                                                self.group, True, self.p_value)
        n_candidates = len(possible_keys)
        logger.debug(f"Caesar returned {n_candidates} candidates")

        candidates = []

        for candidate in possible_keys:
            translated = cipheycore.caesar_decrypt(message, candidate.key,
                                                   self.group)
            candidates.append(
                CrackResult(value=translated, key_info=candidate.key))

        return candidates
Exemple #7
0
    def getInfo(self, ctext: str) -> CrackInfo:
        if self.keysize is not None:
            analysis = self.cache.get_or_update(
                ctext,
                f"vigenere::{self.keysize}",
                lambda: cipheycore.analyse_string(
                    ctext.lower(), self.keysize, self.group
                ),
            )

            val = cipheycore.vigenere_detect(analysis, self.expected)

            logging.info(f"Vigenere has likelihood {val}")

            return CrackInfo(
                success_likelihood=val,
                # TODO: actually calculate runtimes
                success_runtime=1e-3,
                failure_runtime=1e-2,
            )

        likely_lens = self.cache.get_or_update(
            ctext,
            "vigenere::likely_lens",
            lambda: cipheycore.vigenere_likely_key_lens(
                ctext.lower(), self.expected, self.group, self.detect_p_value
            ),
        )

        # Filter out the lens that make no sense
        likely_lens = [i for i in likely_lens if i.len <= self.max_key_length]

        for keysize in likely_lens:
            # Store the analysis
            analysis = self.cache.get_or_update(
                ctext, f"vigenere::{keysize.len}", lambda: keysize.tab
            )
        if len(likely_lens) == 0:
            return CrackInfo(
                success_likelihood=0,
                # TODO: actually calculate runtimes
                success_runtime=2e-3,
                failure_runtime=2e-2,
            )

        logging.info(
            f"Vigenere has likelihood {likely_lens[0].p_value} with lens {[i.len for i in likely_lens]}"
        )

        return CrackInfo(
            success_likelihood=likely_lens[0].p_value,
            # TODO: actually calculate runtimes
            success_runtime=2e-4,
            failure_runtime=2e-4,
        )
Exemple #8
0
    def getInfo(self, ctext: str) -> CrackInfo:
        analysis = self.cache.get_or_update(
            ctext,
            "cipheycore::simple_analysis",
            lambda: cipheycore.analyse_string(ctext),
        )

        return CrackInfo(
            success_likelihood=cipheycore.caesar_detect(analysis, self.expected),
            # TODO: actually calculate runtimes
            success_runtime=1e-5,
            failure_runtime=1e-5,
        )
Exemple #9
0
    def attemptCrack(self, ctext: str) -> List[CrackResult]:
        logger.debug("Trying vigenere cipher")
        # Convert it to lower case
        if self.lower:
            message = ctext.lower()
        else:
            message = ctext

        # Analysis must be done here, where we know the case for the cache
        if self.keysize is not None:
            return self.crackOne(
                message,
                self.cache.get_or_update(
                    ctext,
                    f"vigenere::{self.keysize}",
                    lambda: cipheycore.analyse_string(ctext, self.keysize, self.group),
                ),
            )
        else:
            arrs = []
            possible_len = self.kasiskiExamination(message)
            possible_len.sort()
            logger.trace(f"Got possible lengths {possible_len}")
            # TODO: work out length
            for i in possible_len:
                arrs.extend(
                    self.crackOne(
                        message,
                        self.cache.get_or_update(
                            ctext,
                            f"vigenere::{i}",
                            lambda: cipheycore.analyse_string(ctext, i, self.group),
                        ),
                    )
                )

            logger.debug(f"Vigenere returned {len(arrs)} candidates")
            return arrs
Exemple #10
0
    def getInfo(self, ctext: str) -> CrackInfo:
        if self.keysize is not None:
            analysis = self.cache.get_or_update(
                ctext,
                f"vigenere::{self.keysize}",
                lambda: cipheycore.analyse_string(ctext, self.keysize, self.
                                                  group),
            )

            return CrackInfo(
                success_likelihood=cipheycore.vigenere_detect(
                    analysis, self.expected),
                # TODO: actually calculate runtimes
                success_runtime=1e-4,
                failure_runtime=1e-4,
            )

        likely_lens = self.cache.get_or_update(
            ctext,
            f"vigenere::likely_lens",
            lambda: cipheycore.vigenere_likely_key_lens(
                ctext, self.expected, self.group, self.p_value),
        )

        for keysize in likely_lens:
            # Store the analysis
            analysis = self.cache.get_or_update(ctext,
                                                f"vigenere::{keysize.len}",
                                                lambda: keysize.tab)
        if len(likely_lens) == 0:
            return CrackInfo(
                success_likelihood=0,
                # TODO: actually calculate runtimes
                success_runtime=2e-4,
                failure_runtime=2e-4,
            )

        return CrackInfo(
            success_likelihood=0 * likely_lens[0].p_value,
            # TODO: actually calculate runtimes
            success_runtime=2e-4,
            failure_runtime=2e-4,
        )
Exemple #11
0
    def getInfo(self, ctext: T) -> CrackInfo:
        if self.keysize is not None:
            analysis = self.cache.get_or_update(
                ctext,
                f"vigenere::{self.keysize}",
                lambda: cipheycore.analyse_string(ctext, self.keysize, self.group),
            )

            return CrackInfo(
                success_likelihood=cipheycore.vigenere_detect(analysis, self.expected),
                # TODO: actually calculate runtimes
                success_runtime=1e-4,
                failure_runtime=1e-4,
            )
        else:
            return CrackInfo(
                success_likelihood=0.5,  # TODO: actually work this out
                # TODO: actually calculate runtimes
                success_runtime=1e-4,
                failure_runtime=1e-4,
            )
Exemple #12
0
    def decrypt(self, message):
        logger.debug("Trying caesar Cipher")
        # Convert it to lower case
        #
        # TODO: handle different alphabets
        message = message.lower()

        # Hand it off to the core
        group = cipheydists.get_charset("english")["lcase"]
        expected = cipheydists.get_dist("lcase")
        analysis = cipheycore.analyse_string(message)
        possible_keys = cipheycore.caesar_crack(analysis, expected, group)
        n_candidates = len(possible_keys)
        logger.debug(f"Caesar cipher core heuristic returned {n_candidates} candidates")

        for candidate in possible_keys:
            translated = cipheycore.caesar_decrypt(message, candidate.key, group)
            result = self.lc.checkLanguage(translated)
            if result:
                logger.debug(f"Caesar cipher returns true {result}")
                return {
                    "lc": self.lc,
                    "IsPlaintext?": True,
                    "Plaintext": translated,
                    "Cipher": "Caesar",
                    "Extra Information": f"The rotation used is {candidate.key}",
                }

        # if none of them match English, return false!
        logger.debug(f"Caesar cipher returns false")
        return {
            "lc": self.lc,
            "IsPlaintext?": False,
            "Plaintext": None,
            "Cipher": "Caesar",
            "Extra Information": None,
        }
Exemple #13
0
    def getInfo(self, ctext: bytes) -> CrackInfo:
        if self.keysize is not None:
            analysis = self.cache.get_or_update(
                ctext,
                f"xorcrypt::{self.keysize}",
                lambda: cipheycore.analyse_string(ctext, self.keysize, self.
                                                  group),
            )

            return CrackInfo(
                success_likelihood=cipheycore.xorcrypt_detect(
                    analysis, self.expected),
                # TODO: actually calculate runtimes
                success_runtime=1e-4,
                failure_runtime=1e-4,
            )

        keysize = self.cache.get_or_update(
            ctext,
            f"xorcrypt::likely_lens",
            lambda: cipheycore.xorcrypt_guess_len(ctext),
        )

        if keysize == 1:
            return CrackInfo(
                success_likelihood=0,
                # TODO: actually calculate runtimes
                success_runtime=2e-3,
                failure_runtime=2e-2,
            )

        return CrackInfo(
            success_likelihood=0.9,  # Dunno, but it's quite likely
            # TODO: actually calculate runtimes
            success_runtime=2e-3,
            failure_runtime=2e-2,
        )
Exemple #14
0
import json
import sys

import cipheycore

data = sys.stdin.read()

analysis = cipheycore.analyse_string(data)

print(json.dumps({i: j / len(data) for i, j in analysis.freqs.items()}))