仿射密码的攻击

加法密码和乘法密码的结合就构成了仿射密码,仿射密码加密的思路为:首先将明文乘以密钥的一部分,然后再加上密钥的剩余部分。

一、仿射密码加密解密算法

假设c , m , a , b ∈Z26

加密:ek(m) ≡c ≡ a⋅m + b mod 26 

解密:dk(c) = m = a-1 ⋅(c-b) mod 26

 

密钥为:k =(a ,b ),且满足限制条件 gcd( a ,26)=1。a=1时,仿射密码变为加法密码,当b=0时,仿射密码变为乘法密码
解密可以很容易地从加密函数推导出来:

a ⋅ m  + b≡c mod 26
a ⋅ m≡ (c– b )mod 26
m ≡ a-1⋅ (c– b )mod 26

 

二、C++编程实现仿射密码的攻击

1.问题描述

仿射密码系统用五元组(P,C,K,E,D)表示,设P=C={abcdefghijklmnopqrstuvwxyz}.现在截获了一段密文“ojbkojbk”。请编程分析出明文。

2.C++代码如下:

#include <iostream>
#include <string>
#include <cstdio>
#include<stdlib.h>

using namespace std;
/*
欧几里德算法
*/
int gcd(int a,int b)
{
    int temp;
    if(a<b)//判断大小
    {
        temp=a;
        a=b;
        b=temp;
    }
    if(b==0) return a;
    else return gcd(b,a%b);//递归
}
int main()
{
    string List("abcdefghijklmnopqrstuvwxyz"),c("ojbkojbk"),result;
    int a,b,m,p;
/*
加密:c = Ea,b(m)  ≡ a, + b(mod 26)
解密:m = Da,b(c) ≡ a^-1(c - b)(mod 26)
a,b是密钥 0<=a,b<=n,gcd(a,m)=1
逆元:a^-1*a≡1mod m
*/
    for(a=2;a<26;a++){
        //a和26互素
        if(gcd(a,26)==1){
            //求a的乘法逆元p
            for(b=2;b<26;b++){
                if((a*b)%26==1){
                    p=b;break;
                }
            }
            //下面进行解密
            for(b = 0; b < 28; b++) // k2 = b<q
            {
                for(int i=0;i<c.size();i++){
                     for(int k = 0; k < List.size(); k += 1){
                         if(List[k] == c[i])  //得到密文所对应的密文数字
                         {
                             //string中文测试,因为编码和string类的原因,一个中文字符占两个下标
               //            pp=pp+bi1[k] + bi1[k + 1];
               //            cout<<pp<<endl;
               //            printf("k:%d  ",k);
              //             printf("\n");
                             m = (p * (k - b)) % 26; //得到密文数字相对应的明文数字
                             //得到明文数字对应的明文
                             if (m >= 0)
                             {
                                 result = result + List[m] ;
                             }
                             else
                             {
                                 m = m+ 26;
                                 result = result + List[m];
                             }
                         }
                     }
                }
                 printf ("当 a = %02d, b = %02d 时,解密得到的明文是:   ", a, b);
                 cout << result << endl;
                 result.clear();
           }
        }
    }
    return 0;
}

 

三、运行结果

 

 

 

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我的书包哪里去了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值