玩CTF学密码学2:Caesar(凯撒密码)、Morse(摩斯密码)、二次base64+Unicode转ASCii码

CTF密码学2:

一、Caesar密码:

在这里插入图片描述
不是我说,这题一开始我是真的迷,第一:他说灯笼上是一对 字符,我原来还以为这一对字符是密钥和明文呢,直到我打开附件,这必然不是key啊:
在这里插入图片描述
这里大家可以看到,我们的附件是这个模样,它可能是明文也可能是密文。回看上一道题,答案的格式是:cyberpeace{XXXX}这种格式,这说明啥呢?说明这个附件的大括号前是cyberpeace,然后大括号没有被加密或者解密,这说明这个算法不能管大括号。再加这个题的标题:Caesar,说明是凯撒算法。我们知道凯撒加密算法是一种古典对称加密算法,需要一个密钥key作为移位的步长,可是这个题的密钥呢?我们晓得答案的格式应该是cyberpeace这种款式,那么第一个字符相比:‘o’ - ‘c’ = 12
于是这个移位需要对每个字符向后退12个步长(循环移动)。

解决方案:
Caesar加密算法为: C = E(k, p) = (p + k) mod 26
Caesar解密算法为: p = D(k, C) = (C - k) mod 26

根据上面的观察,得到需要倒退key = 12,于是这是解密,代码如下:


public class Caesar {
    
    
	
	static String src = "oknqdbqmoq{kag_tmhq_xqmdzqp_omqemd_qzodkbfuaz}";
	
	public static void main(String[] args) {
    
    
		StringBuffer ans = new StringBuffer("");
		
		for(int i = 0;i < src.length();++i) {
    
    
			if(src.charAt(i) >= 'a' && src.charAt(i) <= 'z')
			{
    
    
				char iChar = (char)((src.charAt(i) - 'a' - 12 + 26) % 26 + 'a');
				ans.append(iChar);
			}
			else
				ans.append(src.charAt(i));
		}
		
		System.out.println(ans);
		
	}
}

另外Caesar密码还有在线求解网址:

Caesar密码在线加密/解密

二、Morse密码:

在这里插入图片描述

这个题打开后的附件是:
在这里插入图片描述拿到这一串01串,本来我想的是二进制然后对照ASCii码……然后看到题目的标题:Morse,说明是莫斯密码。实话实说,我也没学过Morse密码,然后就去学了一下,看到了这个Morse密码对照表:

在这里插入图片描述
然后我们可看到这个Morse密码的密文对照是由:’-’ 和 ‘.’ 组成,我们的附件上是0和1,那到底是哪种对应方式呢?咱也不知道,但是我们知道最后明文的格式是cyberpeace开头的。我们来看一下,开头第一个是11,这个应该对应字符 ‘c’,首先这个密文key的长度是2,可惜这个密码表上的长度为2,且字符相同(毕竟11是俩相同字符)的对照只有:M……难道这把解出来的不是cyberpeace开头???
但是这样至少我们确定了一点,1对应 ‘-’,0对应’ .’

解决方案:还是Java编程

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.Set;

public class Morse {
    
    
	
	static String src = "11 111 010 000 0 1010 111 100 0 00 000 000 111 00 10 1 0 010 0 000 1 00 10 110";
	
	public static void main(String[] args) {
    
    
		src = src.replace('1', '-');
		src = src.replace('0', '.');
		
		HashMap<String, String> mp = new HashMap<>();
		mp.put("a", ".-");
		mp.put("b", "-...");
		mp.put("c", "-.-.");
		mp.put("d", "-..");
		mp.put("e", ".");
		mp.put("f", "..-.");
		mp.put("g", "--.");
		mp.put("h", "....");
		mp.put("i", "..");
		mp.put("j", ".---");
		mp.put("k", "-.-");
		mp.put("l", ".-..");
		mp.put("m", "--");
		mp.put("n", "-.");
		mp.put("o", "---");
		mp.put("p", ".-");
		mp.put("q", "--.-");
		mp.put("r", ".-.");
		mp.put("s", "...");
		mp.put("t", "-");
		mp.put("u", "..-");
		mp.put("v", "...-");
		mp.put("w", ".--");
		mp.put("x", "-..-");
		mp.put("y", "-.--");
		mp.put("z", "--..");
		mp.put("0", "-----");
		mp.put("1", ".----");
		mp.put("2", "..---");
		mp.put("3", "...--");
		mp.put("4", "....-");
		mp.put("5", ".....");
		mp.put("6", "-....");
		mp.put("7", "--...");
		mp.put("8", "---..");
		mp.put("9", "----.");
		
		HashMap<String, String> MorseDec = new HashMap<>();
		Set<Entry<String, String> > entrySet = mp.entrySet();
		for(Entry<String, String> entry : entrySet) 
			MorseDec.put(entry.getValue(), entry.getKey());
		
		StringBuffer StrTemp = new StringBuffer("");
		StringBuffer ans = new StringBuffer("");
		for(int i = 0;i < src.length();++i) {
    
    
			if(' ' == src.charAt(i))
			{
    
    
				ans.append(MorseDec.get(StrTemp.toString()));
				StrTemp = new StringBuffer("");
			}
			else
				StrTemp.append(src.charAt(i));
		}
		ans.append(MorseDec.get(StrTemp.toString()));
		System.out.println(ans);
	}
}

计算出结果:
在这里插入图片描述
然后一定要记得按照他说的格式,答案就是:

cyberpeace{morsecodeissointeresting}

三、一道综合题:混合编码

在这里插入图片描述
首先是拿到附件,看了一下,那叫一个复杂:
在这里插入图片描述
首先看看,这是尼玛呢……但是大伙还记得上一篇密码学博客吗?我们讲base64加密的时候,说到了不足6位的往后面补一组0,然后完全由补出的0组成的6位编码代表字符 ‘=’ ,这里最后面有俩等号,这提示了我们是不是应该用base64解密呢?这个好长啊,我们来试试看(好在昨天写了Java程序):
在这里插入图片描述
程序跑出来是这么一大堆的东西,搞得我有点烦哦!但是咱们看一下,貌似这些数字有规律啊!如果是ASCii码那就太好了,但是定睛一看,题目说答案都是小写字母……可是这些在ASCii码里早就突破了小写字母的范围了(97-122)上网查才晓得原来这是Unicode编码……话说Unicode编码有啥特征啊,届时我啷个晓得是哪种编码格式哦!

编码格式转换器:好工具!

编码格式转换器!

在这里插入图片描述

Unicode编码:它前128个字符就是ASCII码,之后是扩展码。在Unicode码中,各个字符块基于同样的标准。而汉文,韩语,日语的象形文字占用从0X3000到0X9FFF的代码。
既然我们获得了Unicode编码转成的ASCii编码,那我们就继续看看呗……咋还是这么长的密文……
继续试试base64进行二次解密:
在这里插入图片描述
我们可以看到,这个数字貌似……和我们ASCii码对应的小写字母相对于啊!
继续解析这个ASCii码:
在这里插入图片描述
不是我说,综合题属实还是有点难的,对于我这种CTF小白来说……但是得到Flag就好啦!
最终得到答案:
cyberpeace{welcometoattackanddefenceworld}

本题我的完整代码:

import java.util.Base64;

public class base64 {
    
    
	static String src = "JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzk7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM2ODsmIzY5OyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjNTI7JiM3NjsmIzEyMjsmIzEwNzsmIzUzOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc3OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiMxMDc7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTIwOyYjNzg7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjODQ7JiM2OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzUwOyYjNzY7JiMxMjI7JiM2OTsmIzEyMDsmIzc4OyYjMTA1OyYjNTY7JiM1MzsmIzc4OyYjMTIxOyYjNTY7JiM1MzsmIzc5OyYjODM7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM5OTsmIzExODsmIzc5OyYjODQ7JiM5OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjNjk7JiMxMTk7JiM3NzsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjNjU7JiMxMTg7JiM3NzsmIzg0OyYjNjU7JiMxMjA7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiMxMDU7JiM1NjsmIzEyMDsmIzc3OyYjNjg7JiM2OTsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzExOTsmIzc2OyYjMTIyOyYjMTA3OyYjNTM7JiM3NjsmIzEyMjsmIzY5OyYjMTE5OyYjNzc7JiM4MzsmIzU2OyYjMTIwOyYjNzc7JiM4NDsmIzEwNzsmIzExODsmIzc3OyYjODQ7JiM2OTsmIzEyMDsmIzc2OyYjMTIyOyYjNjk7JiMxMjA7JiM3ODsmIzY3OyYjNTY7JiMxMjA7JiM3NzsmIzY4OyYjMTAzOyYjMTE4OyYjNzc7JiM4NDsmIzY1OyYjMTE5Ow==";
	
	static String NextSrc = "LzExOS8xMDEvMTA4Lzk5LzExMS8xMDkvMTAxLzExNi8xMTEvOTcvMTE2LzExNi85Ny85OS8xMDcvOTcvMTEwLzEwMC8xMDAvMTAxLzEwMi8xMDEvMTEwLzk5LzEwMS8xMTkvMTExLzExNC8xMDgvMTAw";
	public static void main(String[] args) {
    
    
		
		/* 加密 */
//		String Encode = Base64.getEncoder().encodeToString(src.getBytes());
//		System.out.println(Encode);
		
		
		/* 解密 */
		byte[] Decode1 = Base64.getDecoder().decode(src);
		System.out.println(new String(Decode1));
		
		/* 二次解密 */
		byte[] Decode2 = Base64.getDecoder().decode(NextSrc);
		
		String ansAscii = new String(Decode2);
		System.out.println(ansAscii);
		
//		String dec2 = Decode1.toString();
//		byte[] Decode2 = Base64.getDecoder().decode(dec2);
//		System.out.println(new String(Decode2));
		
		StringBuffer Temp = new StringBuffer(""), res = new StringBuffer("");
		for(int i = 0;i < ansAscii.length();++i) {
    
    
			if('/' == ansAscii.charAt(i) && 0 != i)
			{
    
    
				int resTemp = Integer.parseInt(Temp.toString());
				res.append((char)(resTemp));
				Temp = new StringBuffer("");
			}
			else if('0' <= ansAscii.charAt(i) && ansAscii.charAt(i) <= '9')
				Temp.append(ansAscii.charAt(i));
		}
		int resTemp = Integer.parseInt(Temp.toString());
		res.append((char)(resTemp));
		System.out.println(res);
		
	}
	
}

猜你喜欢

转载自blog.csdn.net/qq_44274276/article/details/105385951