2015-01-05 93 views
-3

實現加密算法RSA。具體如下:C私鑰中的RSA算法

  1. 實現算法,將消息轉換爲整數,反之。假設消息僅包含英文字母的字符。
  2. 創建兩個素數p和q大小爲512位。然後計算N,公鑰e及其相應的私鑰d。使用您創建的參數,加密和解密您選擇的消息以檢查實施的正確性。

我的代碼:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include "gmp.h" 
#define BASE 256 
#ifndef MAXLEN 
#define MAXLEN 256 
#endif 
void str_int(mpz_t r, char *str); 
void int_str(char *str, mpz_t org_str_int); 
void eukleidhs(mpz_t a,mpz_t b,mpz_t xx,mpz_t yy); 
gmp_randstate_t stat; 
int main() 
{ 
     gmp_randstate_t rand_state; 
     gmp_randinit_default(rand_state); 
     long sd = 0; 
     mpz_t p, q, p1, q1, n, message_int, a, b, temp_p, temp_q, p_1, q_1, f, e, gcd, d, c, m, A, B, C, D, i, ed, ed_m, fl1, fl2, d1, d2; 
     mpz_t seed; 
     gmp_randinit(stat, GMP_RAND_ALG_LC, 120); 
     mpz_init(p); 
     mpz_init(q); 
     mpz_init(p1); 
     mpz_init(q1); 
     mpz_init(n); 
     mpz_init(p_1); 
     mpz_init(q_1); 
     mpz_init(f); 
     mpz_init(e); 
     mpz_init(fl1); 
     mpz_init(fl2); 
     mpz_init(d1); 
     mpz_init(d2); 
     mpz_init(gcd); 
     mpz_init(d); 
     mpz_init(c); 
     mpz_init(A); 
     mpz_init(m); 
     mpz_init(B); 
     mpz_init(C); 
     mpz_init(D); 
     mpz_init(i); 
     mpz_init(ed); 
     mpz_init(ed_m); 
    mpz_init(message_int); 
    mpz_init(seed); 
     unsigned char message[MAXLEN], out_message[MAXLEN]; 
     mpz_init(a); 
     mpz_init(b); 
     mpz_init(temp_p); 
     mpz_init(temp_q); 
/* (create p 512 BITS)*/ 
     srand((unsigned) getpid()); 
     sd=rand(); 
     mpz_set_ui(seed, sd); 
     gmp_randseed(stat, seed); 
     srand((unsigned) getpid());         
     mpz_set_ui(seed, sd);           
     mpz_urandomb(p1, stat, 512);         
    /* (create q 512 BITS*/ 
srand((unsigned) getpid()); 
sd=rand(); 
mpz_set_ui(seed, sd); 
gmp_randseed(stat, seed); 
srand((unsigned) getpid());         
mpz_set_ui(seed, sd);           
mpz_urandomb(q1, stat, 512);        
     int primetest; 
     primetest = mpz_probab_prime_p(p1, 5); 
     if (primetest != 0) 
     { 
      mpz_set(p, p1); 
      printf("p= "); mpz_out_str(stdout, 10, p); 
      printf("\n"); 
      printf("\n"); 
     } 
     else 
     { 
      mpz_nextprime(p, p1); 
      printf("p= "); mpz_out_str(stdout, 10, p); 
      printf("\n"); 
      printf("\n"); 
     }  
     primetest = mpz_probab_prime_p(q1, 5); 
     if (primetest != 0) 
     { 
      mpz_set(q, q1); 
      printf("q= "); mpz_out_str(stdout, 10, q); 
      printf("\n"); 
      printf("\n"); 
     } 
     else 
     { 
      mpz_nextprime(q, p); 
      printf("q= "); mpz_out_str(stdout, 10, q); 
      printf("\n"); 
      printf("\n");  
     }  
/*(n, p-1, q-1, f)*/ 
     mpz_mul(n, p, q); 
     printf("n= "); mpz_out_str(stdout, 10, n);   // n=p*q 
     printf("\n"); 
     printf("\n"); 
     mpz_sub_ui(p_1, p, 1); 
     printf("p-1= "); mpz_out_str(stdout, 10, p_1);  // p-1 
     printf("\n"); 
     printf("\n"); 
     mpz_sub_ui(q_1, q, 1); 
     printf("q-1= "); mpz_out_str(stdout, 10, q_1);  // q-1 
     printf("\n"); 
     printf("\n"); 
     mpz_mul(f, p_1, q_1); 
     printf("f= "); mpz_out_str(stdout, 10, f);   //f=(p-1)*(q-1) 
     printf("\n"); 
     printf("\n"); 
/*(1<e<f)*/ 
     sequence1: 
     mpz_urandomb(e, stat, 512);     
     if ((mpz_cmp_si(e,1)) && (mpz_cmp (e,f))) 
     { 
      mpz_gcd(gcd, e, f);     
      if (mpz_cmp_si(gcd,1))    
      { 
        printf("To e einai:\n"); 
        printf("e= "); 
        mpz_out_str(stdout, 10, e); 
        printf("\n"); 
        printf("\n"); 
      } 
      else 
      { 
        goto sequence1; 
      } 
     } 

     else 

     { 
      goto sequence1; 
     } 

/*(d WSTE 1<d<f and e*d= 1 mod f)*/ 
     mpz_invert(d, e, f); 
    printf("To d einai:\n"); 
     printf("d= "); 
     mpz_out_str(stdout, 10, d); 
     printf("\n"); 
     printf("\n"); 
/*keys)*/ 
     printf("The public key is :\n");   
     printf("(n,e)= "); 
     printf(" ("); 
     mpz_out_str(stdout, 10, n); 
     printf(" , "); 
     mpz_out_str(stdout, 10, e); 
     printf(") "); 
     printf("\n"); 
     printf("\n"); 
     printf("The private key is:\n");   
     printf("d= "); 
     mpz_out_str(stdout, 10, d); 
     printf("\n"); 
     printf("\n"); 
     printf("GRAPSE TO MYNHMA SOU(Mexri %d xarakthres) !!!! :", MAXLEN); 
     fgets(message, MAXLEN - 1, stdin); 
     str_int(m, message); 
     #ifdef HEX 
     gmp_printf("TO MHNYMA(%d) -> %Zx\n\n", strlen(message), m); // EKTTYPWSH MYNHMATOS SE ARITHMO 
     #else 
     gmp_printf("TO MHNYMA(%d) -> %Zd\n\n", strlen(message), m); 
     #endif 

/*(c = m^e mod n)*/ 

     mpz_powm(c, m, e, n); 
     exit1: 
     printf("TO KRYPTOGRAFHMENO KEIMENO EINAI:\n");   
     printf("c= "); 
     mpz_out_str(stdout, 10, c); 
     printf("\n"); 
     printf("\n"); 

    mpz_set_ui(m,0);   
/*(m = c^d mod n)*/ 
     mpz_powm(m, c, d, n); 
     exit2: 

     printf("TO APOKRYPTOGRAFHMENO KEIMENO EINAI:\n");   
     printf("m= "); 

     mpz_out_str(stdout, 10, m); 

     printf("\n"); 

     printf("\n"); 


     int_str(out_message, m); 

    #ifdef HEX 

     gmp_printf("TO APOKRYPTOGRAFHMENO KEIMENO EINAI: %Zd\n   -> %s(%d)\n", m, out_message, strlen(out_message)); 

     #else 

     gmp_printf("TO APOKRYPTOGRAFHMENO KEIMENO EINAI: %Zd\n   -> %s(%d)\n", m, out_message, strlen(out_message)); 

     #endif 


return 0; 

} 
/* SYNARTHSH METATROPHS STRING SE AKERAIO*/ 

void str_int(mpz_t r, char *str) 

{ 

     long int str_len, j; 

     unsigned char C; 



     str_len = strlen(str); 

     if(str[str_len - 1] == '\n') 

      str[str_len - 1] = '\0'; 

     str_len = strlen(str); 



     mpz_set_ui(r, 0UL);    



     for(j = str_len - 1; j >= 0; j--)   // r = str[str_len - 1] * BASE^(str_len - 1) + ... + str[1] * BASE + str[0] 

     { 

     C = str[j]; 



      mpz_mul_ui(r, r, (unsigned long)BASE);   

      mpz_add_ui(r, r, (unsigned long)C); 

     } 

} 


void int_str(char *str, mpz_t org_str_int) 

{ 

     long int str_len, i; 

     mpz_t max_int, c_int, str_int; 



     mpz_init(max_int);     //ARXIKOPOIHSH 

     mpz_init(c_int); 

     mpz_init(str_int); 



     mpz_set(str_int, org_str_int); 



     mpz_set_ui(max_int, 1UL);   

     for(i = 0; i < MAXLEN; i++) 

     { 

      if(mpz_cmp(str_int, max_int) <= 0) 

      { 

        str_len = i; 
       break; 
      } 

      mpz_mul_ui(max_int, max_int, (unsigned long)BASE); 
     } 

     for(i = 0; i < str_len; i++)  //METATROPH SE GRAMMA 

     { 
      mpz_mod_ui(c_int, str_int, (unsigned long)BASE); 

      mpz_sub(str_int, str_int, c_int); 
      mpz_tdiv_q_ui(str_int, str_int, (unsigned long)BASE); 
      str[i] = mpz_get_ui(c_int); 

     } 

     str[str_len] = '\0'; 

     mpz_clear(max_int); 

     mpz_clear(c_int); 
     mpz_clear(str_int); 

} 
/*ALGORITHMOS EUKLEIDH*/ 

void eukleidhs(mpz_t a,mpz_t b,mpz_t xx,mpz_t yy) 

{ 
     int flag=0; 
     mpz_t d,x,y,x1,x2,y1,y2,q,r; 
     mpz_t qb,a_qb,temp; 
     mpz_t qx1,x2_x1; 
     mpz_t qy1,y2_y1; 
     mpz_init(x); 
     mpz_init(y); 
     mpz_init(d); 

     if(mpz_cmp(b,a)>0) { 

      flag=1; 

      mpz_init(temp); 

      mpz_set(temp,b); 
      mpz_set(b,a); 
      mpz_set(a,temp); 
      mpz_clear(temp); 
     } 

     if(mpz_cmp_ui(b,0)==0) { 

      mpz_set(d,a); 

      mpz_set_ui(x,1); 

      mpz_set_ui(y,0); 

     } 

     else { 

      mpz_init(q); 
      mpz_init(r); 
      mpz_init(x1); 
      mpz_init(x2); 

      mpz_init(y1); 
      mpz_init(y2); 
      mpz_init(qb); 
      mpz_init(a_qb); 
      mpz_init(qx1); 
      mpz_init(qy1); 
      mpz_init(x2_x1);  
      mpz_init(y2_y1); 
      mpz_set_ui(x2,1); 
      mpz_set_ui(x1,0); 
      mpz_set_ui(y1,1); 
      mpz_set_ui(y2,0); 
      while(mpz_cmp_ui(b,0)>0) { 
        mpz_tdiv_q(q,a,b); 
        mpz_mul(qb,q,b);  
        mpz_sub(a_qb,a,qb); 
        mpz_set(r,a_qb); 
        mpz_mul(qx1,q,x1);   
        mpz_sub(x2_x1,x2,qx1); 
        mpz_set(x,x2_x1); 
        mpz_mul(qy1,q,y1);   
        mpz_sub(y2_y1,y2,qy1); 
        mpz_set(y,y2_y1); 
       mpz_set(a,b); 
        mpz_set(b,r); 
        mpz_set(x2,x1); 
        mpz_set(x1,x); 
        mpz_set(y2,y1); 
       mpz_set(y1,y);             
      } 
     } 
     mpz_set(d,a); 
     mpz_set(x,x2); 
     mpz_set(y,y2); 
     if(flag==1){ 
      mpz_set(yy,x); 
      mpz_set(xx,y); 
     } 
     else { 
      mpz_set(yy,y); 
      mpz_set(xx,x); 
     } 
     mpz_clear(d); 
     mpz_clear(x); 
     mpz_clear(y); 
     mpz_clear(x1); 
     mpz_clear(x2); 
     mpz_clear(y1); 
     mpz_clear(y2); 
     mpz_clear(q); 
     mpz_clear(r); 
     mpz_clear(qb); 
     mpz_clear(a_qb); 
     mpz_clear(qx1); 
     mpz_clear(x2_x1); 
     mpz_clear(qy1); 
     mpz_clear(y2_y1); 
} 

我運行該程序,但私鑰出來0,我不能發現其中的錯誤!

+0

代碼中存在大量空行,導致代碼無法讀取。你沒有顯示你的輸入是什麼,或者這些值發生了什麼變化。我沒有跟蹤你是否已經初始化了你聲明的每個變量;有一大堆變量和一桶'mpz_init()'調用,以及另一桶'mpz_clear()'調用,我不知道哪個是哪個,哪個不是。你應該試着讓它使用小數字 - 不需要GMP支持的數字。然後您可以並行驗證內置類型和GMP類型的算法。 –

+0

好的謝謝你的建議 – Stlk

回答

1

最明顯的問題是你反覆重複使用相同的值的系統隨機數發生器,例如,

srand((unsigned) getpid()); 
sd=rand(); 
mpz_set_ui(seed, sd); 
gmp_randseed(stat, seed); 

不要這樣做。您最終每次都得到相同的隨機數,並且很可能將相同的數字重複用於多種用途會帶來不好的結果。