2.4 凯撒密码-lmn-【密码学】小世界-安全文库-NGC660安全实验室

2.4 凯撒密码-lmn

2.4 凯撒密码-lmn

1645784425559-4654a954-7483-4e6e-bf16-d159ce34f48d

0x01 恺撒密码定义

凯撒密码(Caesar cipher)又被称为恺撒加密、恺撒变换、变换加密

提到凯撒密码应该没有人不知道吧,凯撒密码的明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文,简称一种替换密码

也可以认为维吉尼亚密码是一种多凯撒密码的组合

1645784436902-c1e6cbff-0e77-4279-a0d0-f44d69f719e7

恺撒密码名称

偏移量为10:Avocat(A→K)
偏移量为13:ROT13
偏移量为-5:Cassis (K 6)
偏移量为-6:Cassette (K 7)

0x02 ROT13

ROT13(回转13位,rotate by 13 places,有时中间加了个连字符称作ROT-13)
是一种简易的替换式密码,它是一种在英文网络论坛用作隐藏八卦(spoiler)、妙句、谜题解答以及某些脏话的工具,目的是逃过版主或管理员的匆匆一瞥

ROT13被描述成“杂志字谜上下颠倒解答的Usenet点对点体”,也是过去在古罗马开发的凯撒加密的一种变体
例如:
明文:HELLO
密文:URYYB

0x03 凯撒密码原理

首先要确定凯撒密码是有密钥的,凯撒密码的密钥表示字符串每位的移动位数,例如密钥为 5,表示字符串中的每位都左移动五位

例如:
密钥为3
明文字母表:

1645784460417-633a29e5-a8cf-4727-91ed-433e673ee3a2

密文字母表:

1645784468228-ec9a5462-1c23-40b0-96e3-0e699db4eb47

明文:PLAINTEXT
对应密文:SODLQWHAW

加密算法

1645784477226-51e67da6-b11f-452e-9560-806774ae6c86

解密算法

1645784484832-117d44c3-5bb9-402e-a193-de6c7f5650a8

0x04 C语言实现凯撒密码

# -*- coding = utf-8 -*-
# @Time : 2022/2/245 16:26 下午
# @Author : lmn
# @File : Caesar.c
# @Software : CLion

#include <stdio.h>
#include <assert.h>
#define TEXT 100
int CHOOSE()
{
    printf("*******************************\n");
    printf("*** 1. 加密  2. 解密  0. 退出****\n");
    printf("*******************************\n");
    int a = 0;
    scanf("%d",&a);
    return a;
}
//初始化
void InitVirginia(char* text){
    int j = 0;
    for (j = 0; j < TEXT; j++) {
        text[j] = ' ';
    }
}
//加密
int ENCODE(char* plaintext, int key){
    assert(plaintext != NULL);

    //计算 plaintext 元素个数
    int sz = 0;
    for(sz=0;plaintext[sz]!='\0';sz++);
    int i = 0;
    for(i = 0 ; i < sz ; i++)
    {
        if(plaintext[i] >= 'A' && plaintext[i] <= 'Z')
        {
            plaintext[i] = ((plaintext[i]-'A')+key)%26+'A';
        }
        else if(plaintext[i] >= 'a' && plaintext[i] <= 'z')
        {
            plaintext[i] = ((plaintext[i]-'a')+key)%26+'a';
        }
    }
    printf("\n加密后为:%s\n\n",plaintext);
    return 0;
}
//解密
int DECODE(char* ciphertext, int key){
    assert(ciphertext != NULL);
    int sz = 0;
    for(sz=0;ciphertext[sz]!='\0';sz++);
    int i = 0;
    for(i = 0 ; i < sz ; i++)
    {
        if(ciphertext[i] >= 'A' && ciphertext[i] <= 'Z')
        {
            ciphertext[i] = ((ciphertext[i]-'A')-key)%26+'A';
        }
        else if(ciphertext[i] >= 'a' && ciphertext[i] <= 'z')
        {
            ciphertext[i] = ((ciphertext[i]-'a')-key)%26+'a';
        }
    }
    printf("\n加密后为:%s\n\n",ciphertext);

}

int main()
{
    char text[TEXT] = {0};
    char ciphertext[TEXT] = {0};
    int key = 0;
    // 1.选择进行的操作
    int a = 1;
    while(a)
    {
        a = CHOOSE();
        if (a == 0)
            break;
        switch (a) {
            case 1:
                //加密
                InitVirginia(text);
                printf("请输入明文:>");
                scanf("%s",text);
                printf("\n请输入密钥:>");
                scanf("%d",&key);
                ENCODE(text,key);
                break;
            case 2:
                //解密
                InitVirginia(text);
                printf("请输入密文:>");
                scanf("%s",text);
                printf("\n请输入密钥:>");
                scanf("%d",&key);
                DECODE(text, key);
                break;

            default:
                printf("输入有误请重新输入!\n\n");
                //CHOOSE();
        }
    }
    return 0;
}

0x05 python实现凯撒密码

# -*- coding = utf-8 -*-
# @Time : 2022/2/25 9:03 上午
# @Author : lmn
# @File : Caesar.py
# @Software : PyCharm

def encrypt():
    plaintext = input("明文:>")
    keyNumber = int(input("密钥:>"))
    str_list = list(plaintext)
    i = 0
    while len(plaintext) > i:
        if not str_list[i].isalpha():
            str_list[i] = str_list[i]
        else:
            word = "A" if str_list[i].isupper() else "a"
            str_list[i] = chr((ord(str_list[i]) - ord(word) + keyNumber) % 26 + ord(word))
        i = i + 1
    print("明文为:>", ''.join(str_list))


def decrypt():
    ciphertest = input("明文:>")
    keyNumber = int(input("密钥:>"))
    str_list = list(ciphertest)
    i = 0
    while len(ciphertest) > i:
        if not str_list[i].isalpha():
            str_list[i] = str_list[i]
        else:
            word = "A" if str_list[i].isupper() else "a"
            str_list[i] = chr((ord(str_list[i]) - ord(word) - keyNumber) % 26 + ord(word))
        i = i + 1
    print("明文为:>", ''.join(str_list))


def default():
    print("请重新输入:>")


if __name__ == '__main__':
    choise = 1
    while(choise):
        print("*******************************")
        print("*** 1. 加密  2. 解密  0. 退出****")
        print("*******************************")
        choice = input("请输入您想执行哪个操作:>")
        if choice == '0':
            break
        switch = {'1': encrypt,
                  '2': decrypt,
                  }
        switch.get(choice, default)()

自己写的代码,如有不好的地方可私我

0x06 基础CTF题目

1646059922204-04398bbf-99be-46ee-82ff-ad504d76f7cb

题目意思:
caesar 的最大问题是它不允许使用数字或其他字符。
我已经解决了这个问题,现在我可以在明文中使用任何 ascii 字符。
键空间也从 26 个增加到 128 个。\o/

首先根据题目知道为凯撒密码:

1646059934793-97300302-3e9c-4b86-bfe3-84ac8be5fb51
解题思路:将十六进制转换成十进制,再将十进制转换成ascii

tr 命令用于转换或删除文件中的字符

echo "0C 34 34 29 20 2F 34 27 71 20 3E 34 3A 20 38 34
31 3B 2A 29 20 34 33 2A 20 32 34 37 2A 20 28 2D
26 31 31 2A 33 2C 2A 20 2E 33 20 3E 34 3A 37 20
2F 34 3A 37 33 2A 3E 73 20 19 2D 2E 38 20 34 33
2A 20 3C 26 38 20 2B 26 2E 37 31 3E 20 2A 26 38
3E 20 39 34 20 28 37 26 28 30 73 20 1C 26 38 33
6C 39 20 2E 39 04 20 76 77 7D 20 30 2A 3E 38 20
2E 38 20 26 20 36 3A 2E 39 2A 20 38 32 26 31 31
20 30 2A 3E 38 35 26 28 2A 71 20 38 34 20 2E 39
20 38 2D 34 3A 31 29 33 6C 39 20 2D 26 3B 2A 20
39 26 30 2A 33 20 3E 34 3A 20 39 34 34 20 31 34
33 2C 20 39 34 20 29 2A 28 37 3E 35 39 20 39 2D
2E 38 20 32 2A 38 38 26 2C 2A 73 20 1C 2A 31 31
20 29 34 33 2A 71 20 3E 34 3A 37 20 38 34 31 3A
39 2E 34 33 20 2E 38 20 2A 2C 27 27 28 2A 38 2C
35 29 31 38 73 " | tr '\n' ' '

1646059959601-3293eedc-ee14-48ea-a980-468ab356f362

获得目标密文:
0C 34 34 29 20 2F 34 27 71 20 3E 34 3A 20 38 34 31 3B 2A 29 20 34 33 2A 20 32 34 37 2A 20 28 2D 26 31 31 2A 33 2C 2A 20 2E 33 20 3E 34 3A 37 20 2F 34 3A 37 33 2A 3E 73 20 19 2D 2E 38 20 34 33 2A 20 3C 26 38 20 2B 26 2E 37 31 3E 20 2A 26 38 3E 20 39 34 20 28 37 26 28 30 73 20 1C 26 38 33 6C 39 20 2E 39 04 20 76 77 7D 20 30 2A 3E 38 20 2E 38 20 26 20 36 3A 2E 39 2A 20 38 32 26 31 31 20 30 2A 3E 38 35 26 28 2A 71 20 38 34 20 2E 39 20 38 2D 34 3A 31 29 33 6C 39 20 2D 26 3B 2A 20 39 26 30 2A 33 20 3E 34 3A 20 39 34 34 20 31 34 33 2C 20 39 34 20 29 2A 28 37 3E 35 39 20 39 2D 2E 38 20 32 2A 38 38 26 2C 2A 73 20 1C 2A 31 31 20 29 34 33 2A 71 20 3E 34 3A 37 20
Hex = "0C 34 34 29 20 2F 34 27 71 20 3E 34 3A 20 38 34 31 3B 2A 29 20 34 33 2A 20 32 34 37 2A 20 28 2D 26 31 31 2A 33 2C 2A 20 2E 33 20 3E 34 3A 37 20 2F 34 3A 37 33 2A 3E 73 20 19 2D 2E 38 20 34 33 2A 20 3C 26 38 20 2B 26 2E 37 31 3E 20 2A 26 38 3E 20 39 34 20 28 37 26 28 30 73 20 1C 26 38 33 6C 39 20 2E 39 04 20 76 77 7D 20 30 2A 3E 38 20 2E 38 20 26 20 36 3A 2E 39 2A 20 38 32 26 31 31 20 30 2A 3E 38 35 26 28 2A 71 20 38 34 20 2E 39 20 38 2D 34 3A 31 29 33 6C 39 20 2D 26 3B 2A 20 39 26 30 2A 33 20 3E 34 3A 20 39 34 34 20 31 34 33 2C 20 39 34 20 29 2A 28 37 3E 35 39 20 39 2D 2E 38 20 32 2A 38 38 26 2C 2A 73 20 1C 2A 31 31 20 29 34 33 2A 71 20 3E 34 3A 37 20"
Hex = Hex.split()
for shift in range(127):
    for one in Hex:
        Dec =  int(one, 16)+shift+1
        print(chr(Dec % 128), end='')
    print()
    print(shift+1)
    print()

1646059985250-af593152-8e72-4c3c-a8e1-618dc2eb10fc

Good[job,[you[solved[one[more[challenge[in[your[journey.[This[one[was[fairly[easy[to[crack.[Wasn't[it?[128[keys[is[a[quite[small[keyspace,[so[it[shouldn't[have[taken[you[too[long[to[decrypt[this[message.[Well[done,[your[solution[is[egbbcesgpdls.

替换 “}”

echo "Good[job,[you[solved[one[more[challenge[in[your[journey.[This[one[was[fairly[easy[to[crack.[Wasn't[it?[128[keys[is[a[quite[small[keyspace,[so[it[shouldn't[have[taken[you[too[long[to[decrypt[this[message.[Well[done,[your[solution[is[egbbcesgpdls." | tr '[' ' '

1646060016056-6678cfbd-a90b-450c-af92-fa26d13bc44c

请登录后发表评论

    请登录后查看回复内容