如何在尝试解密消息时找出加密密钥

时间:2016-01-05 03:43:45

标签: java encryption cryptography

所以我试图在这里运行我失败的代码,我发现自己正在寻找用于加密消息的密钥,但我什么都没得到。我在寻找这段代码是如何工作的。我应该得到一个已解密的加密邮件,并获取用于加密邮件的两个密钥。在我的测试方法中,我已经包含了需要解密的消息,但是其中一些消息甚至被加密了。例如,我准备好解密这些消息了:

        String decrypt1 = cb.decrypt("UUU VVV EGHI");

        String decrypt2 = cb.decrypt("Pi cddc qt xc iwt rdcutgtcrt gddb lxiw ndjg wpi dc udg p hjgegxht epgin. NTAA ADJS!");

        String decrypt3 = cb.decryptMod("Pi cddc qt xc iwt rdcutgtcrt gddb lxiw ndjg wpi dc udg p hjgegxht epgin. NTAA ADJS!");

        String decTwoKeys = cb.decryptTwoKeys("Hfs cpwewloj loks cd Hoto kyg Cyy.");

        String brake = cb.halfOfString("Qbkm Zgis", 1);

        String decrypt4 = cb.decryptMod(fr.asString());

但是decryptTwoKeys似乎无法使halfOfSring方法正常工作(我将解析后的字符串与索引为1和索引为2的字母混合),也不会打印出解密所需的两个密钥加密的消息。我应该从索引0开始收到一个字母并计算每隔一行,并且每隔一行从索引1获取一个字母,然后在解密隐藏消息后将两个新字符串编译成一个。相反,我为两个键获得0。我知道程序可能需要更长的字符串才能找到这两个键,但是当我使用更长的字符串时,例如当我加载文本文件时,我收到错误Java lang object: out of bounds。我确实得到了一些结果,但程序在解析了一定数量的数据后崩溃了。我还想知道用什么密钥来加密消息

String decrypt2 = cb.decrypt("Pi cddc qt xc iwt rdcutgtcrt gddb lxiw ndjg wpi dc udg p hjgegxht epgin. NTAA ADJS!");

            String decrypt3 = cb.decryptMod("Pi cddc qt xc iwt rdcutgtcrt gddb lxiw ndjg wpi dc udg p hjgegxht epgin. NTAA ADJS!");

以上位工作正常,并解密为正确的消息。

String brake = cb.halfOfString("Qbkm Zgis", 1);

上面的这一点在这个例子中效果很好,因为它打印出bmZi,但在decryptTwoKeys方法中调用时似乎不起作用。

那么如何找出用于加密原始消息的密钥是什么,以及两个,如何找出用于加密的密钥在字符串中

  String decrypt2 = cb.decrypt("Pi cddc qt xc iwt rdcutgtcrt gddb lxiw ndjg wpi dc udg p hjgegxht epgin. NTAA ADJS!");

  String decrypt3 = cb.decryptMod("Pi cddc qt xc iwt rdcutgtcrt gddb lxiw ndjg wpi dc udg p hjgegxht epgin. NTAA ADJS!");

非常感谢任何帮助。

到目前为止,这是我的代码:

import edu.duke.FileResource;


public class CaesarBreaker {

    /**
     * Fint max index in an array
     * @param freqs
     * @return 
     */
    public int maxIndex(int[] freqs) {
        int max = freqs[0];
        for (int i = 1; i < freqs.length; i++) {
            if (freqs[i] > max) {
                max = freqs[i];
            }
        } 
        //System.out.println(max);
        return freqs[max];
        //return max;
    }
    /**
     * 
     * @param message 
     * @return  
     */
    public int[] countLetters(String message) {
        String abc = "abcdefghijklmnopqrstuvwxyz";
        int[] counts = new int[26];
        for (int k = 0; k<message.length(); k++) {
            char ch = Character.toLowerCase(message.charAt(k));
            int dex = abc.indexOf(ch);
            if (dex != -1) {
                counts[dex] += 1;
            }
        }
        //System.out.println(counts);
        return counts;
    }
    /**
     * Decrypt message yhal has been in big letters and encrypted with one key
     * @param encrypted
     * @return 
     */
    public String decrypt (String encrypted) {
        CaesarCipher cc = new CaesarCipher();
        int[] freqs = countLetters(encrypted);
        int maxDex = maxIndex(freqs);
        int dkey = maxDex - 4;
        if(maxDex < 4) {
            dkey = 26 - ( 4 - maxDex);
        }
        //System.out.println(cc.encrypt(encrypted, 25-dkey));
        return cc.encrypt(encrypted, 25-dkey); // we can use encryptMod method
    }







    /**
     * Decrypt message yhal has been in big and small letters and encrypted with one key
     * @param encrypted
     * @return 
     */
    public String decryptMod (String encrypted) {
        CaesarCipherMy ccM = new CaesarCipherMy();
        int[] freqs = countLettersMod(encrypted);
        int maxDex = maxIndex(freqs);
        int dkey = maxDex - 4;
        if(maxDex < 4) {
            dkey = 26 - ( 4 - maxDex);
        }
        //System.out.println(ccM.encryptMod(encrypted, 33-dkey));
        return ccM.encryptMod(encrypted, 33-dkey); // we can use encryptMod method
    }
    public int[] countLettersMod(String message) {
        String abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
        int[] counts = new int[52];
        for (int k = 0; k<message.length(); k++) {
            //char ch = Character.toLowerCase(message.charAt(k));
            char ch = message.charAt(k);
            int dex = abc.indexOf(ch);
            if (dex != -1) {
                counts[dex] += 1;
            }
        }
        //System.out.println(counts);
        return counts;
    }






    /**
     * In order to decrypt the encrypted String, it may be easier to split the String 
     * into two Strings, one String of all the letters encrypted with key1 
     * and one String of all the letters encrypted with key2 . Then use the algorithm from the
     * lesson to determine the key for each String, and then use those keys and the two key
     * encryption method to decrypt the original encrypted message. 
     * For example, if the encrypted message was “Qbkm Zgis” , then you would split this String into
     * two Strings: “Qk gs” , representing the characters in the odd number positions and “bmZi”
     * representing the characters in the even number positions. Then you would get the key for each
     * half String and use the two key encryption method to find the message. Note this example is so
     * small it likely won’t find the keys, but it illustrates how to take the Strings apart.
     * 
     * This method attempts to determine the two keys used to encrypt the message, 
     * prints the two keys, and then returns the decrypted String with those two keys. 
     * More specifically, this method should:
     *     ○ Calculate a String of every other character starting with the first character of the
     *       encrypted String by calling halfOfString.
     *     ○ Calculate a String of every other character starting with the second character of
     *      the encrypted String.
     *     ○ Then calculate the key used to encrypt each half String.
     *     ○ You should print the two keys found.
     *     ○ Calculate and return the decrypted String using the encryptTwoKeys method
     *      from your CaesarCipher class, again making sure it is in the same folder as your
     *      CaesarBreaker class.
     * 
     * @param encrypted
     * @return 
     */
    public String decryptTwoKeys (String encrypted) {
        CaesarCipherMy ccM = new CaesarCipherMy();
        String firstHalf = halfOfString(encrypted, 0);
        String secondHalf = halfOfString(encrypted, 1);
        System.out.println("firstHalf" + "\t" + firstHalf + "\t"  + "secondHalf" + "\t" + secondHalf);

        int firstKey = getKey(firstHalf);
        int secondKey = getKey(secondHalf);

        System.out.println("firstKey" + "\t" + firstKey + "\t"  + "secondKey" + "\t" + secondKey);
        System.out.println(ccM.encryptTwoKeys(encrypted, firstKey, secondKey));
        return ccM.encryptTwoKeys(encrypted, firstKey, secondKey);
    }

    /**
     * This method should return a new String that is every other character from message 
     * starting with the start position. For example, the call halfOfString(“Qbkm Zgis”, 0) 
     * returns the String “Qk gs” and the call halfOfString(“Qbkm Zgis”, 1) returns the String
     * “bm Zi” . Be sure to test this method with a small example.
     * 
     * @param message
     * @param start
     * @return 
     */
    public String halfOfString(String message, int start) {
        if (start != 1 || start != 0) {
        StringBuilder sb = new StringBuilder();
        for (char c : message.toCharArray()) {
            int idx = message.indexOf(c);
            if(idx%2 == start) {
            sb = sb.append(c);
            }
        }
        return sb.toString();
        }
        return null;
    }

    /**
     * This method should call countLetters to get an array of the letter frequencies in String s
     * and then use maxIndex to calculate the index of the largest letter frequency, which is
     * the location of the encrypted letter ‘e’, which leads to the key, which is returned.
     * 
     * @param s 
     * @return  
     */
    public int getKey(String s) {
        int[] freqs = countLettersMod(s);
        return maxIndex(freqs);
    }


    public void testCaesarBreaker() {
        CaesarBreaker cb = new CaesarBreaker();
        FileResource fr = new FileResource();
        CaesarCipherMy ccM = new CaesarCipherMy();



        //("FIRST LEGION ATTACK EAST FLANK!", 23)
        //String decrypt = cb.decrypt("CFOPQ IBDFLK XQQXZH BXPQ CIXKH!");

        //String ret4 = ccM.encrypt("XXX YYY HJKL", 23);
        String decrypt1 = cb.decrypt("UUU VVV EGHI");

        String decrypt2 = cb.decrypt("Pi cddc qt xc iwt rdcutgtcrt gddb lxiw ndjg wpi dc udg p hjgegxht epgin. NTAA ADJS!");

        String decrypt3 = cb.decryptMod("Pi cddc qt xc iwt rdcutgtcrt gddb lxiw ndjg wpi dc udg p hjgegxht epgin. NTAA ADJS!");

        String decTwoKeys = cb.decryptTwoKeys("Hfs cpwewloj loks cd Hoto kyg Cyy.");

        String brake = cb.halfOfString("Qbkm Zgis", 1);

        String decrypt4 = cb.decryptMod(fr.asString());

        //String decrypt5 = cb.decryptMod(fr.asString());

        //String getKey = cb.getKey();
        //System.out.println(ret4);
        //System.out.println(decrypt5);
        System.out.println(decrypt4);

        System.out.println(decrypt1);
        System.out.println(decrypt2);
        System.out.println(decrypt3);
        System.out.println(brake);
        //System.out.println(decTwoKeys);
    }
}

1 个答案:

答案 0 :(得分:0)

您的halfOfString方法存在很多错误。这应该工作:

public static String halfOfString(String message, int start) {
    StringBuilder result = new StringBuilder();
    for (int i = start; i < message.length(); i+=2) {
         result.append(message.charAt(i));
    }
    return result;
}

不幸的是,我觉得你的代码真的很混乱,很可能在其他方法中还有一些错误。