NJUPT 计软院 复习资料

NJUPT【 密码学实验 】

2021-04-27  本文已影响0人  Du1in9

实验一、周期置换,仿射加密,Hill加密

题目:对于明文“In several distributed systems a user should only be able to access data if a user posses a certain set of credentials or attributes Currently the only method for enforcing such policies is to employ a trusted server to store the data and mediate access control However if any server storing the data is compromised then the confidentiality of the data will be compromised In this paper we present a system for realizing complex access control on encrypted data that we call ciphertext-policy attribute-based encryption By using our techniques encrypted data can be kept confidential even if the storage server is untrusted moreover our methods are secure against collusion attacks”(忽略大小写及空格)。
完成(若分组长度不足请自行补足):
a:选择分组 n=7 的周期置换(自定义置换),进行加解密;
b:以 P53 页的 K 作为私钥,进行 Hill 算法加解密,并对明密文字符的频率分别做统计分析。


c:自己选择 K1 和 K2,做仿射密码的加解密,并对明密文字符的频率分别做统计分析。
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    string S="InseveraldistributedsystemsausershouldonlybeabletoaccessdataifauserpossesacertainsetofcredentialsorattributesCurrentlytheonlymethodforenforcingsuchpoliciesistoemployatrustedservertostorethedataandmediateaccesscontrolHoweverifanyserverstoringthedataiscompromisedthentheconfidentialityofthedatawillbecompromisedInthispaperwepresentasystemforrealizingcomplexaccesscontrolonencrypteddatathatwecallciphertext-policyattribute-basedencryptionByusingourtechniquesencrypteddatacanbekeptconfidentialevenifthestorageserverisuntrustedmoreoverourmethodsaresecureagainstcollusionattacksaa";
    cout<<"周期置换前的明文:"<<endl; 
    cout<<S<<endl<<endl; 
    cout<<"自定义密钥:(1 3 5 7 2 6 4)"<<endl<<endl;
    int n=0,i;
    for(i=0;i<S.length()-1;i++){
        char temp0=S[n*7+2];
        char temp1=S[n*7+4];
        char temp2=S[n*7+6];
        char temp3=S[n*7+1];
        char temp4=S[n*7+3];
        char temp5=S[n*7+5];
        char temp6=S[n*7+0];
        
        S[n*7+0]=temp0;
        S[n*7+1]=temp1;
        S[n*7+2]=temp2;
        S[n*7+3]=temp3;
        S[n*7+4]=temp4;
        S[n*7+5]=temp5;
        S[n*7+6]=temp6;
        if(i%7==0){
            n++;
        }
    }
    cout<<"周期置换后的密文:"<<endl; 
    cout<<S<<endl;
    return 0;
}
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    string S="InseveraldistributedsystemsausershouldonlybeabletoaccessdataifauserpossesacertainsetofcredentialsorattributesCurrentlytheonlymethodforenforcingsuchpoliciesistoemployatrustedservertostorethedataandmediateaccesscontrolHoweverifanyserverstoringthedataiscompromisedthentheconfidentialityofthedatawillbecompromisedInthispaperwepresentasystemforrealizingcomplexaccesscontrolonencrypteddatathatwecallciphertextpolicyattributebasedencryptionByusingourtechniquesencrypteddatacanbekeptconfidentialevenifthestorageserverisuntrustedmoreoverourmethodsaresecureagainstcollusionattacksaa";
    cout<<"仿射加密前的明文:"<<endl; 
    cout<<S<<endl<<endl; 
    // 1、字频统计 
    cout<<"明文字频统计:"<<endl;
    for(int i=0;i<26;i++){
        int n=0,N=0;
        for(int j=0;j<S.length();j++){
            if(S[j]==(char)(i+65))
                n++;
            if(S[j]==(char)(i+97))
                N++;
        }
        if(n!=0){
            cout<<(char)(i+65)<<": "<<n*1.0/S.length()<<"\n";
        }
        if(N!=0){
            cout<<(char)(i+97)<<": "<<N*1.0/S.length()<<"\n";
        }
    }
    cout<<"\n";
    // 2、加密 :(k1×m+k2) (mod 26)  
    // 选择 k1=9,k2=2
    int s[S.length()] = {0};
    // 转为数组 
    for(int i=0;i<S.length();i++){
        for(int j=0;j<26;j++){
            if(S[i]==(char)(j+65) || S[i]==(char)(j+97))
                s[i]=j;
        }
    }
    cout<<"仿射加密后的密文:"<<endl; 
    for(int i=0;i<S.length();i++){
        s[i] = (9*s[i]+2)%26;
        cout<<(char)(s[i]+97);
    }   
    cout<<"\n\n";
    // 3、字频统计 
    cout<<"密文字频统计:"<<endl;
    for(int i=0;i<26;i++){
        int n=0;
        for(int j=0;j<S.length();j++){
            if(S[j]==(char)(i+97))
                n++;
        }
        if(n!=0){
            cout<<(char)(i+97)<<": "<<n*1.0/S.length()<<"\n";
        }
    }
    cout<<"\n";
    // 4、解密 : k1^-1(c-k2)(mod 26) 
    // 3×9 = 1(mod26)
    // 9^-1 = 3(mod26)
    cout<<"仿射解密后的密文:"<<endl; 
    for(int i=0;i<S.length();i++){
        int x = 3*(s[i]-2);
        if(x<97)  x+=26;
        cout<<(char)(x%26+97);
    }   
    cout<<"\n";
    return 0;
}
#include <iostream>
#include <cstring>
using namespace std;

int main() {
    string S="InseveraldistributedsystemsausershouldonlybeabletoaccessdataifauserpossesacertainsetofcredentialsorattributesCurrentlytheonlymethodforenforcingsuchpoliciesistoemployatrustedservertostorethedataandmediateaccesscontrolHoweverifanyserverstoringthedataiscompromisedthentheconfidentialityofthedatawillbecompromisedInthispaperwepresentasystemforrealizingcomplexaccesscontrolonencrypteddatathatwecallciphertextpolicyattributebasedencryptionByusingourtechniquesencrypteddatacanbekeptconfidentialevenifthestorageserverisuntrustedmoreoverourmethodsaresecureagainstcollusionattacksaa";
    cout<<"Hill加密前的明文:"<<endl; 
    cout<<S<<endl<<endl; 
    // 1、字频统计 
    cout<<"明文字频统计:"<<endl;
    for(int i=0;i<26;i++){
        int n=0,N=0;
        for(int j=0;j<S.length();j++){
            if(S[j]==(char)(i+65))
                n++;
            if(S[j]==(char)(i+97))
                N++;
        }
        if(n!=0){
            cout<<(char)(i+65)<<": "<<n*1.0/S.length()<<"\n";
        }
        if(N!=0){
            cout<<(char)(i+97)<<": "<<N*1.0/S.length()<<"\n";
        }
    }
    cout<<"\n";
    // 2、加密 
    int k[25] = {10,3,8,0,0,5,14,9,0,0,12,21,11,0,0,0,0,0,11,3,0,0,0,8,7};
    int s[S.length()] = {0};
    // 转为数组 
    for(int i=0;i<S.length();i++){
        for(int j=0;j<26;j++){
            if(S[i]==(char)(j+65) || S[i]==(char)(j+97))
                s[i]=j;
        }
    }
    int ss[S.length()] = {0};
    // 行列式运算 
    for(int i=0;i<S.length()/5;i++){
        for(int j=0;j<5;j++){
            ss[5*i+j]=(s[5*i]*k[j*5+0]+s[5*i+1]*k[j*5+1]+s[5*i+2]*k[j*5+2]+s[5*i+3]*k[j*5+3]+s[5*i+4]*k[j*5+4])%26;
        }
    }       
    // 转为字符 
    for(int i=0;i<S.length();i++){
        for(int j=0;j<26;j++){
            if(ss[i]==j)
                S[i]=(char)(j+65);
        }
    }
    cout<<"Hill加密后的密文:"<<endl; 
    cout<<S<<"\n\n";
    
    // 3、字频统计 
    cout<<"密文字频统计:"<<endl;
    for(int i=0;i<26;i++){
        int n=0;
        for(int j=0;j<S.length();j++){
            if(S[j]==(char)(i+65))
                n++;
        }
        if(n!=0){
            cout<<(char)(i+65)<<": "<<n*1.0/S.length()<<"\n";
        }
    }
    cout<<"\n";
    
    // 4、解密 
    int k1[25] = {21,23,25,0,0,15,2,4,0,0,17,16,3,0,0,0,0,0,7,23,0,0,0,18,11};
    int s1[S.length()] = {0};
    // 行列式运算 
    for(int i=0;i<S.length()/5;i++){
        for(int j=0;j<5;j++){
            s1[5*i+j]=(ss[5*i]*k1[j*5+0]+ss[5*i+1]*k1[j*5+1]+ss[5*i+2]*k1[j*5+2]+ss[5*i+3]*k1[j*5+3]+ss[5*i+4]*k1[j*5+4])%26;
        }
    }       
    // 转为字符 
    for(int i=0;i<S.length();i++){
        for(int j=0;j<26;j++){
            if(s1[i]==j)
                S[i]=(char)(j+65);
        }
    }
    cout<<"Hill解密后的明文:"<<endl; 
    cout<<S<<endl;
    return 0;
}

实验二、AES算法实现

#include <stdio.h>
#define N 4

static unsigned char Sbox[16*16] =  { // S盒 
           //0   1     2     3     4     5     6     7     8     9     a     b     c     d     e     f 
    /*0*/  0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
    /*1*/  0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
    /*2*/  0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
    /*3*/  0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
    /*4*/  0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
    /*5*/  0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
    /*6*/  0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
    /*7*/  0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
    /*8*/  0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
    /*9*/  0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
    /*a*/  0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
    /*b*/  0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
    /*c*/  0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
    /*d*/  0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
    /*e*/  0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
    /*f*/  0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
};

void SubBytes(unsigned char State[N][N]){ 
    int i, j;
    char high, low;
    for (i = 0; i < N; i ++){
        for (j = 0; j < N; j ++){
            low  = State[i][j] & 0x0f; //低4位
            high = (State[i][j] >> 4) & 0x0f; //高4位
            State[i][j] = Sbox[16*high + low];
        }
    }
}

void ShiftRows(unsigned char State[N][N]){
    int shiftnum = 0, i, j, k;
    char tmp;  
    for (i = 0; i < N; i ++){
        for (j = 0; j < shiftnum; j ++){ 
            tmp = State[i][0];
            for (k = 0; k < N-1; k ++){
                State[i][k] = State[i][k+1];
            }
            State[i][k] = tmp;
        }
        shiftnum ++; //移位次数+1
    }
}

/////////////////////////////////////////////////////// 列混合 ↓ 
unsigned char gfmultby01(unsigned char b){ 
    return b;
}

unsigned char gfmultby02(unsigned char b){ 
    if (b < 0x80)
        return (unsigned char)(int)(b <<1);
    else
        return (unsigned char)((int)(b <<1)^(int)(0x1b));
}

unsigned char gfmultby03(unsigned char b){ 
    return (unsigned char) ((int)gfmultby02(b)^(int)b );
}

unsigned char choose(unsigned char a, unsigned char b){
    if (a == 0x01)
        return gfmultby01(b);
    if (a == 0x02)
        return gfmultby02(b);
    if (a == 0x03)
        return gfmultby03(b);
    return b;
}

void MixColumns(unsigned char State[N][N]){ 
    unsigned char mix[N][N] = {
        0x02, 0x03, 0x01, 0x01,
        0x01, 0x02, 0x03, 0x01,
        0x01, 0x01, 0x02, 0x03,
        0x03, 0x01, 0x01, 0x02
    };
    unsigned char tmp[N], end[N][N];
    
    for (int i = 0; i < N; i++){
        for (int j = 0; j < N; j++){
            for (int k = 0; k < N; k++){
                tmp[k] = choose(mix[i][k], State[k][j]);
            }
            end[i][j] = tmp[0] ^ tmp[1] ^ tmp[2] ^ tmp[3];
        }
    }
    for (int i = 0; i < N; i++){
        for (int j = 0; j < N; j++){
            State[i][j] = end[i][j];
        }
    }
}
/////////////////////////////////////////////////////// 列混合 ↑ 

void AddRoundKey(unsigned char State[N][N]){
    unsigned char RoundKey[N][N] = {  
        0xa0, 0x88, 0x23, 0x2a,
        0xfa, 0x54, 0xa3, 0x6c,
        0xfe, 0x2c, 0x39, 0x76,
        0x17, 0xb1, 0x39, 0x05
    };
    for (int j = 0; j < N; j ++){ 
        for (int i = 0; i < N; i ++)
            State[i][j] ^= RoundKey[i][j];
    }
}

void putout(unsigned char s[N][N]){ //输出函数 
    for (int i = 0; i < N; i++){
        for (int j = 0; j < N; j++){
            printf("%2x ", s[i][j]);
        }
        printf("\n");
    }
    printf("\n");
}

int main(){
    unsigned char State[N][N];
    
    printf("请输入数据:");
    for (int i = 0; i < N; i++){
        for (int j = 0; j < N; j++){
            scanf("%x", &State[i][j]); //0x19 0xa0 0x9a 0xe9 0x3d 0xf4 0xc6 0xf8 0xe3 0xe2 0x8d 0x48 0xbe 0x2b 0x2a 0x08
        }
    }
    printf("\n原始数据为:\n");
    putout(State);

    SubBytes(State);
    printf("字节替代后:\n");
    putout(State);

    ShiftRows(State);
    printf("行移位后:\n");
    putout(State);

    MixColumns(State);
    printf("列混合后:\n");
    putout(State);

    AddRoundKey(State);
    printf("轮密钥加后:\n");
    putout(State);
    
    return 0;
}

实验三、SHA1 算法实现

#include <stdio.h>
#include <string.h>
#define S(x,n)  (x<<n|x>>(32-n))    //宏定义S函数为循环左移

static unsigned long m[16],w[80],h[5];

//1、补位:(余数448位)+补长度(64位)=512位 m
static void sha1_pad(char *input, int len){
    int i,n;
    
    for(i=0;i<16;i++){
        m[i] = 0;
    }
    for(i=0;i<len;i++){
        n = 24-((i&0x03)<<3);
        m[i/4] |= input[i]<<n;
    }
    n = 24-((i&0x03)<<3); //11000-i&011<<3
    m[i/4] |= 0x80<<n; //10000000<<n
    m[15] = len*8;
}

//2、由 512位 m生成 80字 w
static void sha1_prepare(void){
    int i;
    for(i=0;i<16;i++){
        w[i]=m[i];
    }
    for(i=16;i<80;i++){
        w[i]=w[i-16]^w[i-14]^w[i-8]^w[i-3];
        w[i]=S(w[i],1); //(w[i]<<n|w[i]>>(32-n))
    }
}

//3、由 80字 w计算 h
static void sha1_calc(void){
    int i;
    unsigned long a,b,c,d,e,f,k,temp;
    
    h[0]=0x67452301;
    h[1]=0xEFCDAB89;
    h[2]=0x98BADCFE;
    h[3]=0x10325476;
    h[4]=0xC3D2E1F0;
    a = h[0];
    b = h[1];//11101111110011011010101110001001
    c = h[2];//10011000101110101101110011111110
    d = h[3];//10000001100100101010001110110
    e = h[4];
    for(i=0;i<80;i++){
        switch(i/20){
        case 0:
            k=0x5A827999;
            f=(b&c)|(~b&d); 
            break;
        case 1:
            k=0x6ED9EBA1;
            f=b^c^d;
            break;
        case 2:
            k=0x8F1BBCDC;
            f=(b&c)|(b&d)|(c&d);
            break;
        case 3:
            k=0xCA62C1D6;
            f=b^c^d;
            break;
        }
        temp=S(a,5)+f+e+w[i]+k;
        e=d;
        d=c;
        c=S(b,30);
        b=a;
        a=temp;
    }
    h[0]+=a;
    h[1]+=b;
    h[2]+=c;
    h[3]+=d;
    h[4]+=e;
}

//input:待校验的数据,len:数据长度(小于56字节)
unsigned long* sha1(char* input, int len){
    sha1_pad(input,len);
    sha1_prepare();
    sha1_calc();
    return h;
}

int main(void){
    char str[1024];
    unsigned long* mac;
    printf("input:");
    gets(str);
    mac=sha1(str,strlen(str));
    printf("SHA1=%08X%08X%08X%08X%08X\n",mac[0],mac[1],mac[2],mac[3],mac[4]);
}

实验四、RSA 算法实现

RSA1.txt 中明文文本为:IHAVEADREAM
RSA2.txt 中加密文本为:C]AVQAJIQAM
RSA3.txt 中解密文本为:IHAVEADREAM

#include<cstring>
#include<iostream>

using namespace std;
const int p=3, q=11, e=7;

int gcd(int e, int phi){
    for(int d=2; ;d++){
        if(d*e%phi == 1)
            return d;
    }
}

// pow(a,b,c) = a^b % c
int pow(int a,int b,int c){
    int res=1;
    for(int i=0;i<b;i++){
        res*=a;
    } 
    return res%c;
}

int main(){
    char ch; 
    // 1、计算 n = p×q,φ(n) = (p-1)×(q-1)
    // 2、计算 d,满足 d*e ≡ 1mod φ(n) 
    // 3、得到:公钥为 {e,n}, 私钥为 {d,n}    
    int n = p*q;
    int phi = (p-1)*(q-1);
    int d = gcd(e,phi);
    
    // 4、加密用公钥,密文:C = M^e (mod n)
    printf("发送方公钥(e,n)为:(%d,%d)\n",e,n);
    freopen("RSA1.txt","r",stdin);
    freopen("RSA2.txt","w",stdout);
    while(scanf("%c",&ch)==1){
        int t = pow(ch-'A',e,n); 
        printf("%c",t+'A');
    }
    fclose(stdin);
    fclose(stdout);
    
    // 5、解密用私钥,明文:M = C^d (mod n) 
    printf("接收方秘钥(d,n)为:(%d,%d)\n",d,n);
    freopen("RSA2.txt","r",stdin);
    freopen("RSA3.txt","w",stdout);
    while(scanf("%c",&ch)==1){
        int t = pow(ch-'A',d,n);   
        printf("%c",t+'A');
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}
上一篇 下一篇

猜你喜欢

热点阅读