恺撒密码 && IDA识别算法

发布时间 2023-06-12 19:59:19作者: Qsons

恺撒密码 && IDA识别算法

恺撒密码原理

恺撒密码,又称恺撒加密、恺撒变换、变换加密。它是一种替换加密的技术。

  • 明文中的所有字母都在字母表上向后(或向前) 按照一个固定数目进行偏移后被替换成密文
  • 当偏移量为3时,所有的字母A会被替换成D, 字母B会被替换成E,以此类推。

特定恺撒密码名称

根据偏移量的不同,还存在若干特定的恺撒密码名称:

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

如何破解恺撒密码?

恺撒密码是一种非常容易破解的加密方式。需要考虑二种情况:

  • 攻击者知道(或者猜测) 密码中使用了某个简单的替换加密方式,但是不确定是恺撒密码

  • 攻击者知道(或者猜测) 使用了恺撒密码,但是不知道其偏移量

    1. 针对于第一种情况,可以通过使用频率分析或者样式单词分析的方法,可以从分析结果中看出规律,得出加密者使用的是恺撒密码。
    2. 针对于第二种情况,因为恺撒密码进行加密是通过字母,所以密码中可以使用的偏移量也是有限的。例如使用26个字母的英语,它的偏移量最多就是25
  • 偏移量26等同于偏移量0,即明文;偏移量超过26,等同于偏移量1-25.

    1. 那其实我们如果通过穷举法的话,可以破解,其中的一个小方法就是在表格中写下密文中的某个偏移使用所有可能的偏移量解密后的内容------称之为候选明文,然后分析表格中的候选明文是否具有实际含义,得到正确的偏移量,解密整个密文。

恺撒密码实例

恺撒密码的替换方法是通过排列明文盒密文字母表,密文字母表示通过将明文字母表向左或向右移动一个固定数目的位置。例如,当偏移量是左移3的时候(解密时的密钥就是3):

  • 明文字母表: ABCDEFGHIJKLMNOPQRSTUVWXYZ
  • 密文字母表: DEFGHIJKLMNOPQRSTUVWXYZABC

当使用时,加密者查找明文字母表中需要加密的消息中的每一个字母所在位置,并且写下密文字母表中对应的字母。而我们如果要得到原来的明文的话,我们就需要根据事先根据的密钥反过来操作。例如:

  • 明文:THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG
  • 密文:WKH TXLFN EURZQ IRA MXPSV RYHU WKH ODCB GRJ。

当然恺撒密码的加密、解密方法也可以通过同余的数学方法进行计算。首先将字母用数字代替,A=0,B=1,...,Z = 25.此时偏移量为n的加密方法即为:

那解密的话就是:

C语言实现恺撒加密算法

#include <stdio.h>
#include <string.h>

int main()
{
	char str[85];
	int offset, i = 0;
	printf("请输入凯撒加密的密文: ");
	while ((str[i++] = getchar()) != '\n');
	str[i] = '\0';
	printf("请输入密钥: ");
	scanf("%d", &offset);

	offset %= 26;//将密钥取模26,确保密钥在0到25之间,控制字母的位移操作

	for (i = 0; i < strlen(str); i++)
	{
		if (str[i] >= 'a' && str[i] <= 'z')//判断明文在a-z之间
		{
			str[i] = (str[i] - 'a' + offset) % 26 + 'a';
		}
		if (str[i] >= 'A' && str[i] <= 'Z')//判断明文在A-Z之间
		{
			str[i] = (str[i] - 'A' + offset) % 26 + 'A';
		}//这里其实可以根据自己的需要来设定凯撒加密
		putchar(str[i]);
	}

	return 0;
}

加密核心语句

if (str[i] >= 'a' && str[i] <= 'z')//判断明文在a-z之间
{
	str[i] = (str[i] - 'a' + offset) % 26 + 'a';
}
  • str[i] - 'a' 指的是将当前字符与小写字母 ' a ' 的ASCII值相减, 得到字母相对于' a '的偏移量
  • +offset 表示在偏移量的基础上加上密钥,实现字母的位移操作
  • % 26 用于确保偏移后的结果是在0到25之间,即保证字母在小写字母的范围内。
  • +'a' 表示将偏移后的结果再加上小写字母' a '的ASCII值,得到加密后的字母。
  1. 总的来说密文 = 原字母相对于' a '的偏移量 + 密钥(即偏移的位数) + 'a'

IDA识别算法

  • 版本Vs2022,Debug
  • x86架构

直接进入到main_0主函数进行分析

int __cdecl main_0(int argc, const char **argv, const char **envp)
{
  char v4; // [esp+0h] [ebp-160h]
  char v5; // [esp+0h] [ebp-160h]
  char v6; // [esp+14h] [ebp-14Ch]
  unsigned int v7; // [esp+E8h] [ebp-78h]
  size_t i; // [esp+E8h] [ebp-78h]
  int v9[3]; // [esp+F4h] [ebp-6Ch] BYREF
  char Str[92]; // [esp+100h] [ebp-60h] BYREF

  __CheckForDebuggerJustMyCode(&unk_41C02B);
  v7 = 0;
  printf_0((char *)&byte_417B30, v4);
  do  //依次获取字符,并存入到Str数组中
  {
    v6 = getchar();
    Str[v7++] = v6;
  }
  while ( v6 != 10 );
  if ( v7 >= 0x55 )
    j____report_rangecheckfailure();
  Str[v7] = 0;
  printf_0((char *)&byte_417B4C, v5);
  printf("%d", (char)v9);
  v9[0] %= 26; //这里可以很明显的看出v9是密钥了,因为这里取模了26,即密钥要控制在26以内
  for ( i = 0; i < j_strlen(Str); ++i )
  {
    if ( Str[i] >= 97 && Str[i] <= 122 )
      Str[i] = (Str[i] + v9[0] - 97) % 26 + 97; //恺撒加密的标志。
      //密文 = 原字母减去'a'的偏移量  +  密钥的长度  + ‘a'
    if ( Str[i] >= 65 && Str[i] <= 90 )
      Str[i] = (Str[i] + v9[0] - 65) % 26 + 65;
    putchar(Str[i]);
  }
  return 0;
}

上述就是恺撒密码在IDA中的识别