玩CTF學密碼學2:Caesar(凱撒密碼)、Morse(摩斯密碼)、二次base64+Unicode轉ASCii碼

CTF密碼學2:

1、Caesar密碼:

在這裏插入圖片描述
不是我說,這題一開始我是真的迷,第一:他說燈籠上是一對 字符,我原來還覺得這一對字符是密鑰和明文呢,直到我打開附件,這必然不是key啊:
在這裏插入圖片描述
這裏你們能夠看到,咱們的附件是這個模樣,它多是明文也多是密文。回看上一道題,答案的格式是:cyberpeace{XXXX}這種格式,這說明啥呢?說明這個附件的大括號前是cyberpeace,而後大括號沒有被加密或者解密,這說明這個算法不能管大括號。再加這個題的標題:Caesar,說明是凱撒算法。咱們知道凱撒加密算法是一種古典對稱加密算法,須要一個密鑰key做爲移位的步長,但是這個題的密鑰呢?咱們曉得答案的格式應該是cyberpeace這種款式,那麼第一個字符相比:‘o’ - ‘c’ = 12
因而這個移位須要對每一個字符向後退12個步長(循環移動)。php

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

根據上面的觀察,獲得須要倒退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密碼在線加密/解密編程

2、Morse密碼:

在這裏插入圖片描述

這個題打開後的附件是:
在這裏插入圖片描述拿到這一串01串,原本我想的是二進制而後對照ASCii碼……而後看到題目的標題:Morse,說明是莫斯密碼。實話實說,我也沒學過Morse密碼,而後就去學了一下,看到了這個Morse密碼對照表:markdown

在這裏插入圖片描述
而後咱們可看到這個Morse密碼的密文對照是由:’-’ 和 ‘.’ 組成,咱們的附件上是0和1,那究竟是哪一種對應方式呢?咱也不知道,可是咱們知道最後明文的格式是cyberpeace開頭的。咱們來看一下,開頭第一個是11,這個應該對應字符 ‘c’,首先這個密文key的長度是2,惋惜這個密碼錶上的長度爲2,且字符相同(畢竟11是倆相同字符)的對照只有:M……難道這把解出來的不是cyberpeace開頭???
可是這樣至少咱們肯定了一點,1對應 ‘-’,0對應’ .’app

解決方案:仍是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);
	}
}

計算出結果:
在這裏插入圖片描述
而後必定要記得按照他說的格式,答案就是:ide

cyberpeace{morsecodeissointeresting}

3、一道綜合題:混合編碼

在這裏插入圖片描述
首先是拿到附件,看了一下,那叫一個複雜:
在這裏插入圖片描述
首先看看,這是尼瑪呢……可是大夥還記得上一篇密碼學博客嗎?咱們講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);
		
	}
	
}
相關文章
相關標籤/搜索