C

时间:2019-01-21 14:40:15

标签: c rsa

我正在尝试为项目使用C语言实现RSA算法。

我可以生成所需的加密/解密密钥,但是似乎无法正确执行加密/解密。 错误似乎在于我如何计算加密邮件。它的数学公式是m ^ e mod n,其中m是消息,e是加密指数,n是公钥和私钥的模数。我使用pow()函数计算m ^ e,并同时使用fmod()函数和%n来计算mod n。似乎都不起作用(给出正确的输出)。

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>

int p1,p2,mod,tot, encExp, decExp, conRelVal;
// Function to check if numbers given are primes
// @param pr: the number being tested
int prime(long int pr){
  int i;
  int j;
  j = sqrt(pr);
  for(i = 2; i <= j; i++){
   if(pr % i == 0)
     return 0;
  }
  return 1;
}

int gcd(int a, int h) 
{ 
    int temp; 
    while (1) 
    { 
        temp = a%h; 
        if (temp == 0) 
          return h; 
        a = h; 
        h = temp; 
    } 
} 

//function to generate encryption key
void encryption_key(){
  p1 = 61;
  p2 = 53;
  conRelVal = 15;
  mod = p1*p2;
  tot = (p1-1)*(p2-1);
  encExp = 12;
  while (encExp < tot){ 
        // e must be co-prime to the totient and 
        // smaller than the totient. 
        if (gcd(encExp,tot)==1) 
            break; 
        else
            encExp++; 
  } 

  decExp = ((1+(conRelVal*tot))/encExp);

printf("p1=%d\np2=%d\nmod=%d\ntot=%d\ne=%d\nd=%d\nconst=%d\n",p1,p2,mod,tot, encExp, decExp, conRelVal);
  printf("Public Key:\t(%d,%d)", mod,encExp);
  printf("\nPrivate Key:\t(%d,%d)", mod,decExp);
}

double encrypt(int msg){
  // Encryption c = (msg ^ e) % n 
  double l;
  l = pow(msg, encExp);
  int j;
  j = ((int)l%mod);
  l = fmod(l, mod);
  printf("\nMessage:\t%d\nEncrypted:\t%lf",msg,l);
  printf("\nMessage:\t%d\nEncrypted:\t%d",msg,j);
  return l;
}

void decrypt(double cyp){
  // Decryption m = (c ^ d) % n 
  double m ;
  m = pow(cyp, decExp);
  int z = ((int)m%mod);     
  m = fmod(m, mod); 
  printf("\nEncrypted:\t%lf\nDecrypted:\t%lf",cyp,m);
  printf("\nEncrypted:\t%lf\nDecrypted:\t%d",cyp,z);
}

int main() { 
  encryption_key();
  int msg = 123;
  double cyp = encrypt(msg);
  decrypt(cyp);
  return 0;
}

Results:  

  $ ./test
p1=61
p2=53
mod=3233
tot=3120
e=17
d=2753
const=15
Public Key:     (3233,17)
Private Key:    (3233,2753)
Message:        123
Encrypted:      992.000000
Message:        123
Encrypted:      -2194
Encrypted:      992.000000
Decrypted:      nan
Encrypted:      992.000000
Decrypted:      -2194

我希望加密为855 并解密为123

2 个答案:

答案 0 :(得分:1)

如上所述,您不能在C数据类型中存储大量数字。解决方法是使用gmp。这是将与您的练习一起使用的代码。丢弃代码的第一部分,假设完成了模分解,它只是在破解私有指数。转到/ *加密功能* /我觉得这很丑...

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <gmp.h>

int main(void)
{
        /* data */
        int p = 61;
        int q = 53;
        size_t e = 17; /* public exponent */
        size_t d;      /* private exponent not given */
        int msg = 123; /* message to be encrypted */
        printf("==============\n");
        printf("DATA\n");
        printf("==============\n");
        printf("int p = %d\n", p);
        printf("int q = %d\n", q);
        printf("int e = %ld\n", e);
        printf("int msg = %d\n\n", msg);

        /* compute modulo n */
        int n = p*q;
        printf("=========================\n");
        printf("1 - Compute n = p * q\n");
        printf("=========================\n");
        printf("n = %d\n\n", n);

        /* compute totient Euler function */
        printf("==========================================================\n");
        printf("2 - Compute totient Euler function phi(n) = (p-1)(q-1)\n");
        printf("==========================================================\n");
        int phi = (p-1) * (q-1);
        printf("totient = %d\n\n", phi);

        /* compute d private exponent */
        printf("==========================================================\n");
        printf("3 - Compute d private exponent d*e mod(phi(n)) = 1\n");
        printf("==========================================================\n");

        for (d = 1; d < ULONG_MAX; d++) {
                int tmp = (d * e)%phi;
                if (tmp == 1) {
                        printf("d is FOUND: %ld\n\n", d);
                        break;
                }
        }

        /* encryption function */
        printf("==========================================================\n");
        printf("4 - ENCRYPTION of message 123 --> enc_msg = m^e mod(n)\n");
        printf("==========================================================\n");
        printf("modulo n = %d\n", n);

        /* we are using gmp to be able to compute very large numbers */
        mpz_t me;      /* message^pub_exp */
        mpz_t enc_msg; /* encrypted message */
        mpz_t modn;    /* modulo n previously computed "3233" */
        mpz_inits(me, enc_msg, modn);
        mpz_set_str(modn, "3233", 10); /* 10 means decimal number */

        mpz_ui_pow_ui(me, msg, e);  /* compute m^e */
        mpz_mod(enc_msg, me, modn); /* compute m^e mod(n) */

        printf("message^e mod(n) = ");
        mpz_out_str(NULL, 10, enc_msg);
        printf("\n\n");


        /* decryption function */
        printf("=============================================================\n");
        printf("5 - DECRYPTION of enc_msg 855 --> dec_msg = enc_msg^d mod(n)\n");
        printf("=============================================================\n");
        printf("modulo n = %d\n", n);

        int enc_message = 855; /* previously computed */
        mpz_t md;              /* enc_message^priv_exp */
        mpz_t dec_msg;         /* decrypted message */
        mpz_inits(md, dec_msg, modn);
        mpz_set_str(modn, "3233", 10);

        mpz_ui_pow_ui(md, enc_message, d);  /* compute enc_message^d */
        mpz_mod(dec_msg, md, modn); /* compute enc_msg^d mod(n) */

        printf("dec_msg^d mod(n) = ");
        mpz_out_str(NULL, 10, dec_msg);
        printf("\n\n");

        /* free */
        mpz_clear(me);
        mpz_clear(md);
        mpz_clear(modn);
        mpz_clear(enc_msg);
        mpz_clear(dec_msg);

        return 0;
}

答案 1 :(得分:0)

通常,编程语言在变量中可以存储的数量方面受到限制。每当您尝试分配一个大于其可存储值的值时,它将环绕/四舍五入为最小值并再次开始计数。

我在这里很难解释。简而言之,我想说的是,您的计算可能出乎意料的错误,因为变量具有可以存储多少值的能力。因此,请确保没有溢出并且计算正确。如果计算结果错误,那么您的输出显然是错误的。