【密码学6】维吉尼亚密码

admin 2025年6月26日01:13:50评论0 views字数 3679阅读12分15秒阅读模式

 

 

【密码学6】维吉尼亚密码

【密码学6】维吉尼亚密码

图片地址:https://bkimg.cdn.bcebos.com/pic/3ac79f3df8dcd100d56d833d748b4710b9122f3c?x-bce-process=image/watermark,image_d2F0ZXIvYmFpa2U4MA==,g_7,xp_5,yp_5/format,f_auto

0x01 维吉尼亚密码

这么“炫酷”的表格就是维吉尼亚密码,先看一下百度百科的介绍:
“维吉尼亚密码(又译维热纳尔密码)是使用一系列凯撒密码组成密码字母表的加密算法,属于多表密码的一种简单形式。”

吉奥万·巴蒂斯塔·贝拉索,意大利密码学家。他的主要著作是于1553年出版的《吉奥万·巴蒂斯塔·贝拉索先生的密码》(La cifra del. Sig. Giovan Battista Bellaso)。
贝拉索1505年出生于一个显赫的家庭。他的父亲是皮尔文森佐(Piervincenzo),是布雷西亚的一位贵族,从15世纪起就在镇上和卡普里亚诺(Capriano)郊区拥有一处房产,位于一个叫做Fenili Belasi(贝拉索的谷仓)的社区,包括圣三一教堂。牧师每年得到一笔固定的薪金和一些柴火。家族的纹章是“在蓝色的田野上三个红舌金狮子头在侧面”。
贝拉索精通研究,擅长数学,在当时这种艺术在所有的意大利宫廷,主要是在罗马教廷享有极大的赞赏。在密码学历史的黄金时期,他只是众多秘书中的一个,他们出于对知识的热爱或真正的需要,在日常活动中尝试新的系统。他的密码标志着一个时代,被认为是四个世纪以来破解不了的。

【密码学6】维吉尼亚密码

吉奥万·巴蒂斯塔·贝拉索是第一个提出多表密码概念的人,但是后来被误认为是布莱斯·德·维吉尼亚所发明,所以也就称之为维吉尼亚密码

0x02 维吉尼亚密码原理

 

【密码学6】维吉尼亚密码

这一一张维吉尼亚的表,可以清楚的看到,这张表由26行,每一行都由前一行字母的顺序向左偏移一位得到

明文为:
VIRGINIACIPHER

密钥为:
SECRETKEY

表格的行代表密钥,列代表明文


明文第1个:V
密文第1个:S     对应密文:N

明文第2个:I
密文第2个:E     对应密文:M

明文第3个:R
密文第3个:C     对应密文:T

明文第4个:G
密文第4个:R     对应密文:X

最后结果为:NMTXMGSEAATJVV

注意:维吉尼亚密码在线加密/解密工具只对字母进行加密,不区分大小写,若文本中出现非字母字符会原样保留!!所以在CTF比赛中可以通过这个很快速的判断出维吉尼亚密码

0x03 维吉尼亚密码CTF题目

题目来自于2022年2月19日的TQLCTF

题目名称:Ranma½

【密码学6】维吉尼亚密码

一开始并无思路只知道是一个日本动画片,其中的编码方式如下

【密码学6】维吉尼亚密码

用sublime打开,看到最后应该是flag

【密码学6】维吉尼亚密码

再重复一遍重点:维吉尼亚密码在线加密/解密工具只对字母进行加密,不区分大小写,若文本中出现非字母字符会原样保留

【密码学6】维吉尼亚密码

逆推思路其实也不难,在不知道维吉尼亚密码的时候应该怎么解?

前面有一串10646-1,根据搜索知道是ISO/IEC 10646-1,根据ISO/IEC 10646-1内容,推测后面为UTF-8,并通过两个关键词找到原文

网址:https://datatracker.ietf.org/doc/html/rfc3629

【密码学6】维吉尼亚密码

原文:

ISO/IEC 10646-1 defines a large character set called the Universal Character Set (UCS) which encompasses most of the world's writing systems.  The originally proposed encodings of the UCS, however, were not compatible with many current applications and protocols, and this has led to the development of UTF-8, the object of this memo.  UTF-8 has the characteristic of preserving the full US-ASCII range, providing compatibility with file systems, parsers and other software that rely on US-ASCII values but are transparent to other values.

仔细分析两端文字,发现相同的单词对应不同的密文,说明不是替换,并且根据大小写和一些线索也排除了换位密码

通过尝试得到两段的ascii分析,如下图:

【密码学6】维吉尼亚密码

根据相减得到的值,发现可能有循环

【密码学6】维吉尼亚密码

根据代码筛选出相减的值,得到循环规律

【密码学6】维吉尼亚密码

以此类推找到flag:TQLCTF{CODIN6_WOQ1D}

不过比赛的时候能省时间还是工具解决吧!

0x04 C语言实现

# -*- coding = utf-8 -*-# @Time : 2022/2/24 9:03 上午# @Author : lmn# @File : Virginia.c# @Software : CLion
#include <stdio.h>#include <assert.h>#define TEXT 100#define TEXT 100#define KEY 50
int CHOOSE(){    printf("*******************************n");    printf("*** 1. 加密  2. 解密  0. 退出****n");    printf("*******************************n");    int a = 0;    scanf("%d",&a);    return a;}//计算密文或明文字符长度长度int TestLen(char* text){    int sz = 0;    for(sz=0;text[sz]!='�';sz++);    return sz;}//初始化void InitVirginia(char* plaintext, char* ciphertext, char* key){    int j = 0;    for (j = 0; j < TEXT; j++) {        plaintext[j] = ' ';        ciphertext[j] = ' ';    }    for (j = 0; j < KEY; j++) {        key[j] = ' ';    }}//加密int ENCODE(char* plaintext, char* key, char* result){    assert(plaintext && key && result);
    //计算 plaintext 元素个数    int sz = TestLen(plaintext);        //计算key元素个数    int sz2 = TestLen(key);
    int i = 0;    for(i = 0 ; i < sz ; i++)    {        result[i] = (plaintext[i] + key[i % sz2] - 'a'-'a')%26 + 'a';    }    printf("n加密后为:%snn",result);    return 0;}//解密int DECODE(char* ciphertext, char* key, char* result){    assert(ciphertext && key && result);
    //计算 ciphertext 元素个数    int sz = TestLen(ciphertext);        //计算key元素个数    int sz2 = TestLen(key);
    int i = 0;    for(i = 0 ; i < sz ; i++)    {        result[i] = (ciphertext[i] + 26 - key[i % sz2])%26 + 'a';    }    printf("n解密后为:%snn",result);    return 0;}int main(){    char plaintext[TEXT] = {0};    char ciphertext[TEXT] = {0};    char key[KEY] = {0};    // 1.选择进行的操作    int a = 1;    while(a)    {        a = CHOOSE();        if (a == 0)            break;        InitVirginia(plaintext, ciphertext, key);        switch (a) {            case 1:                //2.加密                printf("请输入明文:>");                scanf("%s",plaintext);                printf("n请输入密钥:>");                scanf("%s",key);                ENCODE(plaintext,key,ciphertext);                break;            case 2:                //3.解密                printf("请输入密文:>");                scanf("%s",ciphertext);                printf("n请输入密钥:>");                scanf("%s",key);                DECODE(ciphertext, key,plaintext);                break;
            default:                printf("输入有误请重新输入!nn");                        }    }    return 0;}

功能介绍:

  1. 加了初始化函数InitVirginia,可以循环对维吉尼亚密码进行加解密
  2. 防止功能过度繁杂,每次运算时需要计算长度,所以加入了计算长度的函数TestLen
  3. 防止数组为空,加入了断言
  4. C语言初学者可能有地方写的不标准,可加微信一起交流:Claire_lmn

原文始发于微信公众号(Tide安全团队):【密码学6】维吉尼亚密码

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年6月26日01:13:50
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   【密码学6】维吉尼亚密码https://cn-sec.com/archives/813221.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息