導航:首頁 > 源碼編譯 > rsa加密解密演算法c語言

rsa加密解密演算法c語言

發布時間:2023-09-08 16:07:52

① 如何用C語言實現RSA演算法

上學期交的作業,已通過老師在運行時間上的測試
#include <stdio.h>
#include <stdlib.h>

unsigned long prime1,prime2,ee;

unsigned long *kzojld(unsigned long p,unsigned long q) //擴展歐幾里得演算法求模逆
{
unsigned long i=0,a=1,b=0,c=0,d=1,temp,mid,ni[2];
mid=p;
while(mid!=1)
{
while(p>q)
{p=p-q; mid=p;i++;}
a=c*(-1)*i+a;b=d*(-1)*i+b;
temp=a;a=c;c=temp;
temp=b;b=d;d=temp;
temp=p;p=q;q=temp;
i=0;
}
ni[0]=c;ni[1]=d;
return(ni);
}

unsigned long momi(unsigned long a,unsigned long b,unsigned long p) //模冪演算法
{
unsigned long c;
c=1;
if(a>p) a=a%p;
if(b>p) b=b%(p-1);
while(b!=0)
{
while(b%2==0)
{
b=b/2;
a=(a*a)%p;
}
b=b-1;
c=(a*c)%p;
}
return(c);
}

void RSAjiami() //RSA加密函數
{
unsigned long c1,c2;
unsigned long m,n,c;
n=prime1*prime2;
system("cls");
printf("Please input the message:\n");
scanf("%lu",&m);getchar();
c=momi(m,ee,n);
printf("The cipher is:%lu",c);
return;
}

void RSAjiemi() //RSA解密函數
{
unsigned long m1,m2,e,d,*ni;
unsigned long c,n,m,o;
o=(prime1-1)*(prime2-1);
n=prime1*prime2;
system("cls");
printf("Please input the cipher:\n");
scanf("%lu",&c);getchar();
ni=kzojld(ee,o);
d=ni[0];
m=momi(c,d,n);
printf("The original message is:%lu",m);
return;
}

void main()
{ unsigned long m;
char cho;
printf("Please input the two prime you want to use:\n");
printf("P=");scanf("%lu",&prime1);getchar();
printf("Q=");scanf("%lu",&prime2);getchar();
printf("E=");scanf("%lu",&ee);getchar();
if(prime1<prime2)
{m=prime1;prime1=prime2;prime2=m;}
while(1)
{
system("cls");
printf("\t*******RSA密碼系統*******\n");
printf("Please select what do you want to do:\n");
printf("1.Encrpt.\n");
printf("2.Decrpt.\n");
printf("3.Exit.\n");
printf("Your choice:");
scanf("%c",&cho);getchar();
switch(cho)
{ case '1':RSAjiami();break;
case '2':RSAjiemi();break;
case '3':exit(0);
default:printf("Error input.\n");break;
}
getchar();
}
}

② RSA加密解密演算法示例(C語言)

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

#include <math.h>

#include <time.h>

#define PRIME_MAX 200   // 生成素數范圍

#define EXPONENT_MAX 200 // 生成指數e范圍

#define Element_Max 127    // 加密單元的最大值,這里為一個char, 即1Byte

char str_read[100]="hello world !";  // 待加密的原文

int str_encrypt[100];                // 加密後的內容

char str_decrypt[100];              // 解密出來的內容

int str_read_len;                    // str_read 的長度

int prime1, prime2;                  // 隨機生成的兩個質數

int mod, eular;                      // 模數和歐拉數

int pubKey, priKey;                  // 公鑰指數和私鑰指數

// 生成隨機素數,實際應用中,這兩個質數越大,就越難破解。

int randPrime()

{

int prime, prime2, i;

next:

prime = rand() % PRIME_MAX;   // 隨機產生數

if (prime <= 1) goto next;      // 不是質數,生成下一個隨機數

if (prime == 2 || prime == 3) return prime;

prime2 = prime / 2;              // prime>=4, prime2 的平方必定大於 prime , 因此只檢查小於等於prime2的數

for (i = 2; i <= prime2; i++)   // 判斷是否為素數

{

if (i * i > prime) return prime;

if (prime % i == 0) goto next;  // 不是質數,生成下一個隨機數

}

}

// 歐幾里德演算法,判斷a,b互質

int gcd(int a, int b)

{

int temp;

while (b != 0) {

temp = b;

b = a % b;

a = temp;

}

return a;

}

//生成公鑰指數,條件是 1< e < 歐拉數,且與歐拉數互質。

int randExponent()

{

int e;

while (1)

{

e = rand() % eular; if (e < EXPONENT_MAX) break;

}

while (1)

{

if (gcd(e, eular) == 1) return e; e = (e + 1) % eular; if (e == 0 || e > EXPONENT_MAX) e = 2;

}

}

//生成私鑰指數

int inverse()

{

int d, x;

while (1)

{

d = rand() % eular;

x = pubKey * d % eular;

if (x == 1)

{

return d;

}

}

}

//加密函數

void jiami()           

{

str_read_len = strlen(str_read);      //從參數表示的地址往後找,找到第一個'\0',即串尾。計算'\0'至首地址的「距離」,即隔了幾個字元,從而得出長度。

printf("密文是:");

for (int i = 0; i < str_read_len; i++)

{

int C = 1; int a = str_read[i], b = a % mod;

for (int j = 0; j < pubKey; j++) //實現加密

{

C = (C*b) % mod;

}

str_encrypt[i] = C;

printf("%d ", str_encrypt[i]);

}

printf("\n");

}

//解密函數

void jiemi()         

{

int i=0;  for (i = 0; i < str_read_len; i++)

{

int C = 1; int a = str_encrypt[i], b=a%mod;

for (int j = 0; j < priKey; j++)

{

C = (C * b) % mod;

}

str_decrypt[i] = C;

}

str_decrypt[i] = '\0'; printf("解密文是:%s \n", str_decrypt);

}

int main()

{

srand(time(NULL));

while (1)

{

prime1 = randPrime(); prime2 = randPrime(); printf("隨機產生兩個素數:prime1 = %d , prime2 = %d ", prime1, prime2);

mod = prime1 * prime2; printf("模數:mod = prime1 * prime2 = %d \n", mod); if (mod > Element_Max) break; // 模數要大於每個加密單元的值

}

eular = (prime1 - 1) * (prime2 - 1);  printf("歐拉數:eular=(prime1-1)*(prime2-1) = %d \n", eular);

pubKey = randExponent(); printf("公鑰指數:pubKey = %d\n", pubKey);

priKey = inverse(); printf("私鑰指數:priKey = %d\n私鑰為 (%d, %d)\n", priKey, priKey, mod);

jiami(); jiemi();

return 0;

}

③ 如何用C語言來使用openssl rsa進行公鑰加密,已有公鑰和明文

1. 本程序使用2048位密鑰對,每次加密時,原始數據的最大長度為245位元組,加密後的密文長度為256位元組.(採用打PADDING 的加密方式)

2. 如果所加密數據長度大於245位元組,請分多次加密,後將密文按順序存儲;解密時,每次讀取256位元組,進行解密,將解密後的數據依次按順序存儲,即可還原原始數據.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/err.h>
#define OPENSSLKEY "test.key"
#define PUBLICKEY "test_pub.key"
#define BUFFSIZE 1024
char *my_encrypt(char *str, char *path_key); //加密
char *my_decrypt(char *str, char *path_key); //解密
int main(void)
{
char *source = "i like dancing !!!";
char *ptf_en, *ptf_de;
printf("source is :%s\n", source);
//1.加密
ptf_en = my_encrypt(source, PUBLICKEY);
if (ptf_en == NULL){
return 0;
}else{
printf("ptf_en is :%s\n", ptf_en);
}
//2.解密
ptf_de = my_decrypt(ptf_en, OPENSSLKEY);
if (ptf_de == NULL){
return 0;
}else{
printf("ptf_de is :%s\n", ptf_de);
}
if(ptf_en) free(ptf_en);
if(ptf_de) free(ptf_de);
return 0;
}
//加密
char *my_encrypt(char *str, char *path_key)
{
char *p_en = NULL;
RSA *p_rsa = NULL;
FILE *file = NULL;
int lenth = 0; //flen為源文件長度, rsa_len為秘鑰長度
//1.打開秘鑰文件
if((file = fopen(path_key, "rb")) == NULL)
{
perror("fopen() error 111111111 ");
goto End;
}
//2.從公鑰中獲取 加密的秘鑰
if((p_rsa = PEM_read_RSA_PUBKEY(file, NULL,NULL,NULL )) == NULL)
{
ERR_print_errors_fp(stdout);
goto End;
}
lenth = strlen(str);
p_en = (char *)malloc(256);
if(!p_en)
{
perror("malloc() error 2222222222");
goto End;
}
memset(p_en, 0, 256);
//5.對內容進行加密
if(RSA_public_encrypt(lenth, (unsigned char*)str, (unsigned char*)p_en, p_rsa, RSA_PKCS1_PADDING) < 0)
{
perror("RSA_public_encrypt() error 2222222222");
goto End;
}
End:
//6.釋放秘鑰空間, 關閉文件
if(p_rsa) RSA_free(p_rsa);
if(file) fclose(file);
return p_en;
}
//解密
char *my_decrypt(char *str, char *path_key)
{
char *p_de = NULL;
RSA *p_rsa = NULL;
FILE *file = NULL;
//1.打開秘鑰文件
file = fopen(path_key, "rb");
if(!file)
{
perror("fopen() error 22222222222");
goto End;
}
//2.從私鑰中獲取 解密的秘鑰
if((p_rsa = PEM_read_RSAPrivateKey(file, NULL,NULL,NULL )) == NULL)
{
ERR_print_errors_fp(stdout);
goto End;
}
p_de = (char *)malloc(245);
if(!p_de)
{
perror("malloc() error ");
goto End;
}
memset(p_de, 0, 245);
//5.對內容進行加密
if(RSA_private_decrypt(256, (unsigned char*)str, (unsigned char*)p_de, p_rsa, RSA_PKCS1_PADDING) < 0)
{
perror("RSA_public_encrypt() error ");
goto End;
}
End:
//6.釋放秘鑰空間, 關閉文件
if(p_rsa) RSA_free(p_rsa);
if(file) fclose(file);
return p_de;
}

④ RSA加密演算法怎樣用C語言實現 急急急!!!

/*數據只能是大寫字母組成的字元串。
加密的時候,輸入Y,然後輸入要加密的文本(大寫字母)
解密的時候,輸入N,然後輸入一個整數n表示密文的個數,然後n個整數表示加密時候得到的密文。
*/
/*RSA algorithm */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MM 7081
#define KK 1789
#define PHIM 6912
#define PP 85
typedef char strtype[10000];
int len;
long nume[10000];
int change[126];
char antichange[37];

void initialize()
{ int i;
char c;
for (i = 11, c = 'A'; c <= 'Z'; c ++, i ++)
{ change[c] = i;
antichange[i] = c;
}
}
void changetonum(strtype str)
{ int l = strlen(str), i;
len = 0;
memset(nume, 0, sizeof(nume));
for (i = 0; i < l; i ++)
{ nume[len] = nume[len] * 100 + change[str[i]];
if (i % 2 == 1) len ++;
}
if (i % 2 != 0) len ++;
}
long binamod(long numb, long k)
{ if (k == 0) return 1;
long curr = binamod (numb, k / 2);
if (k % 2 == 0)
return curr * curr % MM;
else return (curr * curr) % MM * numb % MM;
}
long encode(long numb)
{ return binamod(numb, KK);
}
long decode(long numb)
{ return binamod(numb, PP);
}
main()
{ strtype str;
int i, a1, a2;
long curr;
initialize();
puts("Input 'Y' if encoding, otherwise input 'N':");
gets(str);
if (str[0] == 'Y')
{ gets(str);
changetonum(str);
printf("encoded: ");
for (i = 0; i < len; i ++)
{ if (i) putchar('-');
printf(" %ld ", encode(nume[i]));
}
putchar('\n');
}
else
{ scanf("%d", &len);
for (i = 0; i < len; i ++)
{ scanf("%ld", &curr);
curr = decode(curr);
a1 = curr / 100;
a2 = curr % 100;
printf("decoded: ");
if (a1 != 0) putchar(antichange[a1]);
if (a2 != 0) putchar(antichange[a2]);
}
putchar('\n');
}
putchar('\n');
system("PAUSE");
return 0;
}

/*
測試:
輸入:
Y
FERMAT
輸出:
encoded: 5192 - 2604 - 4222
輸入
N
3 5192 2604 4222
輸出
decoded: FERMAT
*/

⑤ 如何用C語言實現RSA演算法

RSA演算法它是第一個既能用於數據加密也能用於數字簽名的演算法。它易於理解和操作,也很流行。演算法的名字以發明者的名字
命名:Ron Rivest, Adi Shamir 和Leonard
Adleman。但RSA的安全性一直未能得到理論上的證明。它經歷了各種攻擊,至今未被完全攻破。

一、RSA演算法 :

首先, 找出三個數, p, q, r,
其中 p, q 是兩個相異的質數, r 是與 (p-1)(q-1) 互質的數
p, q, r 這三個數便是 private key

接著, 找出 m, 使得 rm == 1 mod (p-1)(q-1)
這個 m 一定存在, 因為 r 與 (p-1)(q-1) 互質, 用輾轉相除法就可以得到了
再來, 計算 n = pq
m, n 這兩個數便是 public key

編碼過程是, 若資料為 a, 將其看成是一個大整數, 假設 a < n
如果 a >= n 的話, 就將 a 表成 s 進位 (s <= n, 通常取 s = 2^t),
則每一位數均小於 n, 然後分段編碼
接下來, 計算 b == a^m mod n, (0 <= b < n),
b 就是編碼後的資料

解碼的過程是, 計算 c == b^r mod pq (0 <= c < pq),
於是乎, 解碼完畢 等會會證明 c 和 a 其實是相等的 :)

如果第三者進行竊聽時, 他會得到幾個數: m, n(=pq), b
他如果要解碼的話, 必須想辦法得到 r
所以, 他必須先對 n 作質因數分解
要防止他分解, 最有效的方法是找兩個非常的大質數 p, q,
使第三者作因數分解時發生困難
<定理>
若 p, q 是相異質數, rm == 1 mod (p-1)(q-1),
a 是任意一個正整數, b == a^m mod pq, c == b^r mod pq,
則 c == a mod pq

證明的過程, 會用到費馬小定理, 敘述如下:
m 是任一質數, n 是任一整數, 則 n^m == n mod m
(換另一句話說, 如果 n 和 m 互質, 則 n^(m-1) == 1 mod m)
運用一些基本的群論的知識, 就可以很容易地證出費馬小定理的

<證明>
因為 rm == 1 mod (p-1)(q-1), 所以 rm = k(p-1)(q-1) + 1, 其中 k 是整數
因為在 molo 中是 preserve 乘法的
(x == y mod z and u == v mod z => xu == yv mod z),
所以, c == b^r == (a^m)^r == a^(rm) == a^(k(p-1)(q-1)+1) mod pq

1. 如果 a 不是 p 的倍數, 也不是 q 的倍數時,
則 a^(p-1) == 1 mod p (費馬小定理) => a^(k(p-1)(q-1)) == 1 mod p
a^(q-1) == 1 mod q (費馬小定理) => a^(k(p-1)(q-1)) == 1 mod q
所以 p, q 均能整除 a^(k(p-1)(q-1)) - 1 => pq | a^(k(p-1)(q-1)) - 1
即 a^(k(p-1)(q-1)) == 1 mod pq
=> c == a^(k(p-1)(q-1)+1) == a mod pq

2. 如果 a 是 p 的倍數, 但不是 q 的倍數時,
則 a^(q-1) == 1 mod q (費馬小定理)
=> a^(k(p-1)(q-1)) == 1 mod q
=> c == a^(k(p-1)(q-1)+1) == a mod q
=> q | c - a
因 p | a
=> c == a^(k(p-1)(q-1)+1) == 0 mod p
=> p | c - a
所以, pq | c - a => c == a mod pq

3. 如果 a 是 q 的倍數, 但不是 p 的倍數時, 證明同上

4. 如果 a 同時是 p 和 q 的倍數時,
則 pq | a
=> c == a^(k(p-1)(q-1)+1) == 0 mod pq
=> pq | c - a
=> c == a mod pq
Q.E.D.

這個定理說明 a 經過編碼為 b 再經過解碼為 c 時, a == c mod n (n = pq)
但我們在做編碼解碼時, 限制 0 <= a < n, 0 <= c < n,
所以這就是說 a 等於 c, 所以這個過程確實能做到編碼解碼的功能

二、RSA 的安全性

RSA的安全性依賴於大數分解,但是否等同於大數分解一直未能得到理論上的證明,因為沒有證明破解
RSA就一定需要作大數分解。假設存在一種無須分解大數的演算法,那它肯定可以修改成為大數分解演算法。目前, RSA
的一些變種演算法已被證明等價於大數分解。不管怎樣,分解n是最顯然的攻擊方法。現在,人們已能分解多個十進制位的大素數。因此,模數n
必須選大一些,因具體適用情況而定。

三、RSA的速度

由於進行的都是大數計算,使得RSA最快的情況也比DES慢上倍,無論是軟體還是硬體實現。速度一直是RSA的缺陷。一般來說只用於少量數據加密。

四、RSA的選擇密文攻擊

RSA在選擇密文攻擊面前很脆弱。一般攻擊者是將某一信息作一下偽裝( Blind),讓擁有私鑰的實體簽署。然後,經過計算就可得到它所想要的信息。實際上,攻擊利用的都是同一個弱點,即存在這樣一個事實:乘冪保留了輸入的乘法結構:

( XM )^d = X^d *M^d mod n

前面已經提到,這個固有的問題來自於公鑰密碼系統的最有用的特徵--每個人都能使用公鑰。但從演算法上無法解決這一問題,主要措施有兩條:一條是採用好的公
鑰協議,保證工作過程中實體不對其他實體任意產生的信息解密,不對自己一無所知的信息簽名;另一條是決不對陌生人送來的隨機文檔簽名,簽名時首先使用
One-Way HashFunction 對文檔作HASH處理,或同時使用不同的簽名演算法。在中提到了幾種不同類型的攻擊方法。

五、RSA的公共模數攻擊

若系統中共有一個模數,只是不同的人擁有不同的e和d,系統將是危險的。最普遍的情況是同一信息用不同的公鑰加密,這些公鑰共模而且互質,那末該信息無需私鑰就可得到恢復。設P為信息明文,兩個加密密鑰為e1和e2,公共模數是n,則:

C1 = P^e1 mod n

C2 = P^e2 mod n

密碼分析者知道n、e1、e2、C1和C2,就能得到P。

因為e1和e2互質,故用Euclidean演算法能找到r和s,滿足:

r * e1 + s * e2 = 1

假設r為負數,需再用Euclidean演算法計算C1^(-1),則

( C1^(-1) )^(-r) * C2^s = P mod n

另外,還有其它幾種利用公共模數攻擊的方法。總之,如果知道給定模數的一對e和d,一是有利於攻擊者分解模數,一是有利於攻擊者計算出其它成對的e』和d』,而無需分解模數。解決辦法只有一個,那就是不要共享模數n。

RSA的小指數攻擊。 有一種提高 RSA速度的建議是使公鑰e取較小的值,這樣會使加密變得易於實現,速度有
所提高。但這樣作是不安全的,對付辦法就是e和d都取較大的值。

RSA演算法是
第一個能同時用於加密和數字簽名的演算法,也易於理解和操作。RSA是被研究得最廣泛的公鑰演算法,從提出到現在已近二十年,經歷了各種攻擊的考驗,逐漸為人
們接受,普遍認為是目前最優秀的公鑰方案之一。RSA的安全性依賴於大數的因子分解,但並沒有從理論上證明破譯RSA的難度與大數分解難度等價。即RSA
的重大缺陷是無法從理論上把握它的保密性能
如何,而且密碼學界多數人士傾向於因子分解不是NPC問題。
RSA的缺點主要有:A)產生密鑰很麻煩,受到素數產生技術的限制,因而難以做到一次一密。B)分組長度太大,為保證安全性,n 至少也要 600
bits
以上,使運算代價很高,尤其是速度較慢,較對稱密碼演算法慢幾個數量級;且隨著大數分解技術的發展,這個長度還在增加,不利於數據格式的標准化。目
前,SET( Secure Electronic Transaction )協議中要求CA採用比特長的密鑰,其他實體使用比特的密鑰。

C語言實現

#include <stdio.h>
int candp(int a,int b,int c)
{ int r=1;
b=b+1;
while(b!=1)
{
r=r*a;
r=r%c;
b--;
}
printf("%d\n",r);
return r;
}
void main()
{
int p,q,e,d,m,n,t,c,r;
char s;
printf("please input the p,q: ");
scanf("%d%d",&p,&q);
n=p*q;
printf("the n is %3d\n",n);
t=(p-1)*(q-1);
printf("the t is %3d\n",t);
printf("please input the e: ");
scanf("%d",&e);
if(e<1||e>t)
{
printf("e is error,please input again: ");
scanf("%d",&e);
}
d=1;
while(((e*d)%t)!=1) d++;
printf("then caculate out that the d is %d\n",d);
printf("the cipher please input 1\n");
printf("the plain please input 2\n");
scanf("%d",&r);
switch(r)
{
case 1: printf("input the m: "); /*輸入要加密的明文數字*/
scanf("%d",&m);
c=candp(m,e,n);
printf("the cipher is %d\n",c);break;
case 2: printf("input the c: "); /*輸入要解密的密文數字*/
scanf("%d",&c);
m=candp(c,d,n);
printf("the cipher is %d\n",m);break;
}
getch();
}

⑥ 求正確的RSA加密解密演算法C語言的,多謝。

//rsa.h
#include<stdio.h>
#defineMAX_NUM63001
#defineMAX_PRIME251

//!返回代碼
#defineOK100
#defineERROR_NOEACHPRIME101
#defineERROR_NOPUBLICKEY102
#defineERROR_GENERROR103

unsignedintMakePrivatedKeyd(unsignedintuiP,unsignedintuiQ);
unsignedintGetPrivateKeyd(unsignedintiWhich);
unsignedintMakePairkey(unsignedintuiP,unsignedintuiQ,unsignedintuiD);
unsignedintGetPairKey(unsignedint&d,unsignedint&e);
voidrsa_encrypt(intn,inte,char*mw,intiLength,int*&cw);
voidrsa_decrypt(intn,intd,int*&cw,intcLength,char*mw);
voidoutputkey();

//rsa.c
#include"rsa.h"
//!保存私鑰d集合
structpKeyset
{
unsignedintset[MAX_NUM];
unsignedintsize;
}pset;

//!保存公、私鑰對
structpPairkey
{
unsignedintd;
unsignedinte;
unsignedintn;
}pairkey;

//名稱:isPrime
//功能:判斷兩個數是否互質
//參數:m:數a;n:數b
//返回:m、n互質返回true;否則返回false

boolisPrime(unsignedintm,unsignedintn)
{
unsignedinti=0;
boolFlag=true;

if(m<2||n<2)
returnfalse;

unsignedinttem=(m>n)?n:m;
for(i=2;i<=tem&&Flag;i++)
{
boolmFlag=true;
boolnFlag=true;
if(m%i==0)
mFlag=false;
if(n%i==0)
nFlag=false;
if(!mFlag&&!nFlag)
Flag=false;
}
if(Flag)
returntrue;
else
returnfalse;
}

//名稱:MakePrivatedKeyd
//功能:由素數Q、Q生成私鑰d
//參數:uiP:素數P;uiQ:素數Q
//返回:私鑰d

unsignedintMakePrivatedKeyd(unsignedintuiP,unsignedintuiQ)
{
unsignedinti=0;

//!得到所有與z互質的數(私鑰d的集合)
unsignedintz=(uiP-1)*(uiQ-1);
pset.size=0;
for(i=0;i<z;i++)
{
if(isPrime(i,z))
{
pset.set[pset.size++]=i;
}
}

returnpset.size;
}

//名稱:MakePairKey
//功能:生成RSA公、私鑰對
//參數:uiP:素數P;uiQ:素數Q;uiD:私鑰d
//返回:錯誤代碼

unsignedintMakePairkey(unsignedintuiP,unsignedintuiQ,unsignedintuiD)
{
boolbFlag=true;
unsignedinti=0,e;
unsignedintz=(uiP-1)*(uiQ-1);
unsignedintd=pset.set[uiD];
//d=uiD;

if(!isPrime(z,d))
returnERROR_NOEACHPRIME;

for(i=2;i<z;i++)
{
if((i*d)%z==1)
{
e=i;
bFlag=false;
}
}
if(bFlag)
returnERROR_NOPUBLICKEY;

if((d*e)%z!=1)
ERROR_GENERROR;

pairkey.d=d;
pairkey.e=e;
pairkey.n=uiP*uiQ;
returnOK;
}

//名稱:GetPairKey
//功能:對外提供介面,獲得公、私鑰對
//參數:uiP:素數P;uiQ:素數Q;uiD:私鑰d
//返回:

unsignedintGetPairKey(unsignedint&d,unsignedint&e)
{
d=pairkey.d;
e=pairkey.e;
returnpairkey.n;
}

//名稱:GetPrivateKeyd
//功能:對外提供介面,由用戶選擇ID得以私鑰d
//參數:iWhich:用戶選擇私鑰d的ID
//返回:私鑰d值

unsignedintGetPrivateKeyd(unsignedintiWhich)
{
if(pset.size>=iWhich)
returnpset.set[iWhich];
else
return0;
}

//名稱:rsa_encrypt
//功能:RSA加密運算
//參數:n:公鑰n;e:公鑰e;mw:加密明文;iLength:明文長度;cw:密文輸出
//返回:無

voidrsa_encrypt(intn,inte,char*mw,intmLength,int*&cw)
{
inti=0,j=0;
__int64temInt=0;

for(i=0;i<mLength;i++)
{
temInt=mw[i];
if(e!=0)
{
for(j=1;j<e;j++)
{
temInt=(temInt*mw[i])%n;
}
}
else
{
temInt=1;
}

cw[i]=(int)temInt;
}
}

//名稱:rsa_decrypt
//功能:RSA解密運算
//參數:n:私鑰n;d:私鑰d;cw:密文;cLength:密文長度;mw:明文輸出
//返回:無

voidrsa_decrypt(intn,intd,int*&cw,intcLength,char*mw)
{
inti=0,j=-1;
__int64temInt=0;

for(i=0;i<cLength/4;++i)
{
mw[i]=0;
temInt=cw[i];

if(d!=0)
{
for(j=1;j<d;j++)
{
temInt=(__int64)(temInt*cw[i])%n;
}
}
else
{
temInt=1;
}

mw[i]=(char)temInt;
}
}
voidoutputkey()
{
printf("PublicKey(e,n):(%d,%d) ",pairkey.e,pairkey.n);
printf("PrivateKey(d,n):(%d,%d) ",pairkey.d,pairkey.n);
}

//main.c
//工程:RSA
//功能:RSA加、解密文件
//作者:jlcss|ExpNIS


#include<stdio.h>
#include<afxwin.h>
#include<math.h>
#include"rsa.h"

#defineDECRYPT_FILE"RSA加密密文.txt"
#defineENCRYPT_FILE"RSA解密明文.txt"
//!約束文件最大2M
#defineMAX_FILE1024*1024*2

//名稱:usage
//功能:幫助信息
//參數:應用程序名稱
//返回:提示信息

voidUsage(constchar*appname)
{
printf(" usage:rsa-k素數P素數Q ");
printf(" usage:rsa-e明文文件公鑰e公鑰n ");
printf(" usage:rsa-d密文文件私鑰d私鑰n ");
}

//名稱:IsNumber
//功能:判斷數字字元數組
//參數:strNumber:字元數組
//返回:數字字組數組返回true,否則返回false;

boolIsNumber(constchar*strNumber)
{
unsignedinti;

if(!strNumber)
returnfalse;

for(i=0;i<strlen(strNumber);i++)
{
if(strNumber[i]<'0'||strNumber[i]>'9')
returnfalse;
}

returntrue;
}

//名稱:IsPrimeNumber
//功能:判斷素數
//參數:num:輸入整數
//返回:素數返回true,否則返回false;

boolIsPrimeNumber(unsignedintnum)
{
unsignedinti;
if(num<=1)
returnfalse;

unsignedintsqr=(unsignedint)sqrt((double)num);
for(i=2;i<=sqr;i++)
{
if(num%i==0)
returnfalse;
}

returntrue;
}

//名稱:FileIn
//功能:讀取磁碟文件到內存
//參數:strFile:文件名稱;inBuff:指向文件內容緩沖區
//返回:實際讀取內容大小(位元組)

intFileIn(constchar*strFile,unsignedchar*&inBuff)
{
intiFileLen=0,iBuffLen=0;

//!打開密文文件
CFilefile(strFile,CFile::modeRead);
iFileLen=(int)file.GetLength();
if(iFileLen>MAX_FILE)
{
printf("文件長度不能大於%dM,! ",MAX_FILE/(1024*1024));
gotoout;
}
iBuffLen=iFileLen;

inBuff=newunsignedchar[iBuffLen];
if(!inBuff)
gotoout;

ZeroMemory(inBuff,iBuffLen);

file.Read(inBuff,iFileLen);
file.Close();

out:
returniBuffLen;
}

//名稱:FileOut
//功能:加/解密結果輸出到當前目錄磁碟文件中
//參數:strOut指向輸出字元緩沖區,輸出大小len,strFile為輸出文件
//返回:無

voidFileOut(constvoid*strOut,intlen,constchar*strFile)
{
//!輸出到文件
CFileoutfile(strFile,CFile::modeCreate|CFile::modeWrite);
outfile.Write(strOut,len);
outfile.Close();
}

//名稱:CheckParse
//功能:校驗應用程序入口參數
//參數:argc等於main主函數argc參數,argv指向main主函數argv參數
//返回:若參數合法返回true,否則返回false
//備註:簡單的入口參數校驗

boolCheckParse(intargc,char**argv)
{
boolbRes=false;

if(argc!=4&&argc!=5)
gotoout;

if(argc==4&&argv[1][1]=='k')
{
//!生成公、私鑰對
if(!IsNumber(argv[2])||
!IsNumber(argv[3])||
atoi(argv[2])>MAX_PRIME||
atoi(argv[3])>MAX_PRIME)
gotoout;
}
elseif((argc==5)&&(argv[1][1]=='e'||argv[1][1]=='d'))
{
//!加密、解密操作
if(!IsNumber(argv[3])||
!IsNumber(argv[4])||
atoi(argv[3])>MAX_NUM||
atoi(argv[4])>MAX_NUM)
gotoout;
}
else
Usage(*argv);
bRes=true;

out:
returnbRes;
}

//名稱:kOption1
//功能:程序k選項操作:由素數P、Q生成私鑰d集合
//參數:uiP:程序入口參數P;uiQ:程序入口參數Q
//返回:執行正確返回生成私鑰數目,否則返回0

unsignedintkOption1(unsignedintuiP,unsignedintuiQ)
{
unsignedintuiRes=0;

if(!IsPrimeNumber(uiP))
{
printf("P輸入錯誤,P必須為(0,%d]素數",MAX_PRIME);
returnuiRes;
}
if(!IsPrimeNumber(uiQ))
{
printf("Q輸入錯誤,Q必須為(0,%d]素數",MAX_PRIME);
returnuiRes;
}
if(uiP==uiQ)
{
printf("素數P與素數Q相同,很容易根據公鑰n開平方得出素數P和Q,這種加密不安全,請更換素數! ");
returnuiRes;
}
printf("正在生成私鑰d集合...... ");
uiRes=MakePrivatedKeyd(uiP,uiQ);

returnuiRes;
}

//!程序主函數
intmain(intargc,char**argv)
{
unsignedintp,q,d,n,e;//twoprimep&q,publickey(n,e),privatekey(n,d)
CheckParse(argc,argv);

d=4828;//uid
if(argc==4)
{
p=atoi(argv[2]);
q=atoi(argv[3]);
MakePrivatedKeyd(p,q);
MakePairkey(p,q,d);
outputkey();
}
elseif(argc==5)
{
charFileName[20];
strcpy(FileName,argv[2]);
intlen;
if(argv[1][1]=='e')
{
unsignedchar*inBuffer=(unsignedchar*)malloc(MAX_FILE);//輸入緩沖區
int*cw=(int*)malloc(MAX_FILE);
len=FileIn(FileName,inBuffer);
e=atoi(argv[3]);
n=atoi(argv[4]);
rsa_encrypt(n,e,(char*)inBuffer,len,cw);
FileOut(cw,4*len,DECRYPT_FILE);
}
elseif(argv[1][1]=='d')
{
char*Buffer=(char*)malloc(MAX_FILE);//輸入緩沖區
int*cw=(int*)malloc(MAX_FILE);
len=FileIn(FileName,(unsignedchar*&)cw);
d=atoi(argv[3]);
n=atoi(argv[4]);
rsa_decrypt(n,d,cw,len,Buffer);
FileOut(Buffer,len/4,ENCRYPT_FILE);
}
}

return0;
}

閱讀全文

與rsa加密解密演算法c語言相關的資料

熱點內容
連漲啟動源碼 瀏覽:161
小奔運動app網路異常怎麼回事 瀏覽:447
php開啟壓縮 瀏覽:303
伺服器主機如何設置啟動 瀏覽:282
linux配置網路命令 瀏覽:774
一張照片怎麼製作視頻app 瀏覽:908
pythonweb和php 瀏覽:976
電腦伺服器地址ip地址 瀏覽:823
對矩陣壓縮是為了 瀏覽:910
setfacl命令 瀏覽:172
linux子系統中斷 瀏覽:342
linux查看進程ps 瀏覽:224
知識庫系統php 瀏覽:623
小波變換壓縮圖像python 瀏覽:151
阿里巴巴程序員怎麼月入百萬 瀏覽:173
如何使用國外伺服器 瀏覽:188
燃燈者pdf 瀏覽:468
編譯器用數學嗎 瀏覽:7
圖形化apk反編譯工具 瀏覽:48
考勤表加密怎麼辦 瀏覽:736