仿射密碼的攻擊

加法密碼和乘法密碼的結合就構成了仿射密碼,仿射密碼加密的思路爲:首先將明文乘以密鑰的一部分,然後再加上密鑰的剩餘部分。

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

假設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;
}

 

三、運行結果

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章